diff --git a/Implem.CodeDefiner/Implem.CodeDefiner.csproj b/Implem.CodeDefiner/Implem.CodeDefiner.csproj index c4b316318..f1f473328 100644 --- a/Implem.CodeDefiner/Implem.CodeDefiner.csproj +++ b/Implem.CodeDefiner/Implem.CodeDefiner.csproj @@ -5,9 +5,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 This program does the automatic code creation and merging of existing code based on the definition. Also it will make the configuration change of sql server database. - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 Linux diff --git a/Implem.DefinitionAccessor/Def.cs b/Implem.DefinitionAccessor/Def.cs index aac3782f2..8b564255f 100644 --- a/Implem.DefinitionAccessor/Def.cs +++ b/Implem.DefinitionAccessor/Def.cs @@ -575,9 +575,11 @@ public static void SetCodeDefinition() case "Model_SetByApi_ColumnCases": Code.Model_SetByApi_ColumnCases = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApi_ColumnCases, definitionRow, CodeXls); break; case "Model_SetByApi_ColumnCasesGroupMembers": Code.Model_SetByApi_ColumnCasesGroupMembers = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApi_ColumnCasesGroupMembers, definitionRow, CodeXls); break; case "Model_SetByApi_ColumnCasesSite": Code.Model_SetByApi_ColumnCasesSite = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApi_ColumnCasesSite, definitionRow, CodeXls); break; + case "Model_SetByApi_ImageHash": Code.Model_SetByApi_ImageHash = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApi_ImageHash, definitionRow, CodeXls); break; case "Model_SetByApi_RecordPermissions": Code.Model_SetByApi_RecordPermissions = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApi_RecordPermissions, definitionRow, CodeXls); break; case "Model_SetByApi_Site": Code.Model_SetByApi_Site = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApi_Site, definitionRow, CodeXls); break; case "Model_SetByApiExec": Code.Model_SetByApiExec = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApiExec, definitionRow, CodeXls); break; + case "Model_SetByApiImages": Code.Model_SetByApiImages = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApiImages, definitionRow, CodeXls); break; case "Model_SetByApiParameter": Code.Model_SetByApiParameter = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByApiParameter, definitionRow, CodeXls); break; case "Model_SetByCsvRow": Code.Model_SetByCsvRow = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByCsvRow, definitionRow, CodeXls); break; case "Model_SetByCsvRowColumnCases": Code.Model_SetByCsvRowColumnCases = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Model_SetByCsvRowColumnCases, definitionRow, CodeXls); break; @@ -1002,6 +1004,7 @@ public static void SetCodeDefinition() case "SiteSettings_GetModels_Items": Code.SiteSettings_GetModels_Items = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.SiteSettings_GetModels_Items, definitionRow, CodeXls); break; case "SiteSettings_GetModels_Items_Choices": Code.SiteSettings_GetModels_Items_Choices = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.SiteSettings_GetModels_Items_Choices, definitionRow, CodeXls); break; case "SiteSettings_GetModels_Items_SiteIntegration": Code.SiteSettings_GetModels_Items_SiteIntegration = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.SiteSettings_GetModels_Items_SiteIntegration, definitionRow, CodeXls); break; + case "SiteSettings_Users": Code.SiteSettings_Users = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.SiteSettings_Users, definitionRow, CodeXls); break; case "Summaries": Code.Summaries = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Summaries, definitionRow, CodeXls); break; case "Summaries_DataTablesCases": Code.Summaries_DataTablesCases = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Summaries_DataTablesCases, definitionRow, CodeXls); break; case "Summaries_ParamCases": Code.Summaries_ParamCases = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.Summaries_ParamCases, definitionRow, CodeXls); break; @@ -1803,6 +1806,7 @@ public static void SetColumnDefinition() case "Tenants_ContractDeadline": Column.Tenants_ContractDeadline = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_ContractDeadline, definitionRow, ColumnXls); break; case "Tenants_ContractSettings": Column.Tenants_ContractSettings = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_ContractSettings, definitionRow, ColumnXls); break; case "Tenants_DisableAllUsersPermission": Column.Tenants_DisableAllUsersPermission = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_DisableAllUsersPermission, definitionRow, ColumnXls); break; + case "Tenants_DisableApi": Column.Tenants_DisableApi = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_DisableApi, definitionRow, ColumnXls); break; case "Tenants_DisableStartGuide": Column.Tenants_DisableStartGuide = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_DisableStartGuide, definitionRow, ColumnXls); break; case "Tenants_HtmlTitleRecord": Column.Tenants_HtmlTitleRecord = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_HtmlTitleRecord, definitionRow, ColumnXls); break; case "Tenants_HtmlTitleSite": Column.Tenants_HtmlTitleSite = definitionRow[1].ToString(); SetColumnTable(ColumnTable.Tenants_HtmlTitleSite, definitionRow, ColumnXls); break; @@ -6872,9 +6876,11 @@ public class CodeColumn2nd public string Model_SetByApi_ColumnCases; public string Model_SetByApi_ColumnCasesGroupMembers; public string Model_SetByApi_ColumnCasesSite; + public string Model_SetByApi_ImageHash; public string Model_SetByApi_RecordPermissions; public string Model_SetByApi_Site; public string Model_SetByApiExec; + public string Model_SetByApiImages; public string Model_SetByApiParameter; public string Model_SetByCsvRow; public string Model_SetByCsvRowColumnCases; @@ -7299,6 +7305,7 @@ public class CodeColumn2nd public string SiteSettings_GetModels_Items; public string SiteSettings_GetModels_Items_Choices; public string SiteSettings_GetModels_Items_SiteIntegration; + public string SiteSettings_Users; public string Summaries; public string Summaries_DataTablesCases; public string Summaries_ParamCases; @@ -7634,9 +7641,11 @@ public class CodeTable public CodeDefinition Model_SetByApi_ColumnCases = new CodeDefinition(); public CodeDefinition Model_SetByApi_ColumnCasesGroupMembers = new CodeDefinition(); public CodeDefinition Model_SetByApi_ColumnCasesSite = new CodeDefinition(); + public CodeDefinition Model_SetByApi_ImageHash = new CodeDefinition(); public CodeDefinition Model_SetByApi_RecordPermissions = new CodeDefinition(); public CodeDefinition Model_SetByApi_Site = new CodeDefinition(); public CodeDefinition Model_SetByApiExec = new CodeDefinition(); + public CodeDefinition Model_SetByApiImages = new CodeDefinition(); public CodeDefinition Model_SetByApiParameter = new CodeDefinition(); public CodeDefinition Model_SetByCsvRow = new CodeDefinition(); public CodeDefinition Model_SetByCsvRowColumnCases = new CodeDefinition(); @@ -8061,6 +8070,7 @@ public class CodeTable public CodeDefinition SiteSettings_GetModels_Items = new CodeDefinition(); public CodeDefinition SiteSettings_GetModels_Items_Choices = new CodeDefinition(); public CodeDefinition SiteSettings_GetModels_Items_SiteIntegration = new CodeDefinition(); + public CodeDefinition SiteSettings_Users = new CodeDefinition(); public CodeDefinition Summaries = new CodeDefinition(); public CodeDefinition Summaries_DataTablesCases = new CodeDefinition(); public CodeDefinition Summaries_ParamCases = new CodeDefinition(); @@ -8883,6 +8893,7 @@ public class ColumnColumn2nd public string Tenants_ContractDeadline; public string Tenants_ContractSettings; public string Tenants_DisableAllUsersPermission; + public string Tenants_DisableApi; public string Tenants_DisableStartGuide; public string Tenants_HtmlTitleRecord; public string Tenants_HtmlTitleSite; @@ -9418,6 +9429,7 @@ public class ColumnTable public ColumnDefinition Tenants_ContractDeadline = new ColumnDefinition(); public ColumnDefinition Tenants_ContractSettings = new ColumnDefinition(); public ColumnDefinition Tenants_DisableAllUsersPermission = new ColumnDefinition(); + public ColumnDefinition Tenants_DisableApi = new ColumnDefinition(); public ColumnDefinition Tenants_DisableStartGuide = new ColumnDefinition(); public ColumnDefinition Tenants_HtmlTitleRecord = new ColumnDefinition(); public ColumnDefinition Tenants_HtmlTitleSite = new ColumnDefinition(); diff --git a/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj b/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj index e7989ed56..06ca0a44f 100644 --- a/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj +++ b/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Implem.DefinitionAccessor/Initializer.cs b/Implem.DefinitionAccessor/Initializer.cs index e9a7494eb..2854c9f6c 100644 --- a/Implem.DefinitionAccessor/Initializer.cs +++ b/Implem.DefinitionAccessor/Initializer.cs @@ -181,6 +181,10 @@ public static void SetParameters() Parameters.Security.AspNetCoreDataProtection.KeyIdentifier, Environment.GetEnvironmentVariable($"{Parameters.Service.EnvironmentName}_Security_AspNetCoreDataProtection_KeyIdentifier"), Environment.GetEnvironmentVariable($"{Parameters.Service.Name}_Security_AspNetCoreDataProtection_KeyIdentifier")); + Parameters.Service.DeploymentEnvironment = Strings.CoalesceEmpty( + Parameters.Service.DeploymentEnvironment, + Environment.GetEnvironmentVariable($"{Parameters.Service.EnvironmentName}_Service_DeploymentEnvironment"), + Environment.GetEnvironmentVariable($"{Parameters.Service.Name}_Service_DeploymentEnvironment")); } public static void ReloadParameters() @@ -888,15 +892,6 @@ private static void SetColumnDefinitionAccessControl() Def.ColumnDefinitionCollection.FirstOrDefault(o => o.Id == "Users_AllowGroupCreation").UpdateAccessControl = "ManageService"; } - if (!Parameters.User.DisableApi) - { - Def.ColumnDefinitionCollection.FirstOrDefault(o => - o.Id == "Users_AllowApi").CreateAccessControl = "ManageService"; - Def.ColumnDefinitionCollection.FirstOrDefault(o => - o.Id == "Users_AllowApi").ReadAccessControl = "ManageService"; - Def.ColumnDefinitionCollection.FirstOrDefault(o => - o.Id == "Users_AllowApi").UpdateAccessControl = "ManageService"; - } switch (Parameters.Security.SecondaryAuthentication?.Mode) { case SecondaryAuthentication.SecondaryAuthenticationMode.None: diff --git a/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj b/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj index ec6b8924f..9df5c5b7f 100644 --- a/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj +++ b/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Implem.Factory/Implem.Factory.csproj b/Implem.Factory/Implem.Factory.csproj index f6daf83c0..b30d17622 100644 --- a/Implem.Factory/Implem.Factory.csproj +++ b/Implem.Factory/Implem.Factory.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Implem.Libraries/Implem.Libraries.csproj b/Implem.Libraries/Implem.Libraries.csproj index ca8eb9bdd..5dc9a2d3c 100644 --- a/Implem.Libraries/Implem.Libraries.csproj +++ b/Implem.Libraries/Implem.Libraries.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj b/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj index a99faac12..c51c0dd2d 100644 --- a/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj +++ b/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Implem.ParameterAccessor/Parts/BackgroundService.cs b/Implem.ParameterAccessor/Parts/BackgroundService.cs index bc76d284a..81016a970 100644 --- a/Implem.ParameterAccessor/Parts/BackgroundService.cs +++ b/Implem.ParameterAccessor/Parts/BackgroundService.cs @@ -1,9 +1,12 @@ -using System.Collections.Generic; +using Implem.DefinitionAccessor; +using System.Collections.Generic; +using System.Linq; namespace Implem.ParameterAccessor.Parts { public class BackgroundService { + public List EnvironmentVariables; public bool Reminder; public int ReminderIgnoreConsecutiveExceptionCount; public bool SyncByLdap; @@ -16,12 +19,27 @@ public class BackgroundService public List DeleteTrashBoxTime; public int DeleteTrashBoxRetentionPeriod; - public bool TimerEnabled() + public bool TimerEnabled(string deploymentEnvironment) { - return SyncByLdap + return ServiceEnabled(deploymentEnvironment) + && (SyncByLdap || DeleteSysLogs || DeleteTemporaryFiles - || DeleteTrashBox; + || DeleteTrashBox); + } + + public bool ReminderEnabled(string deploymentEnvironment) + { + return Reminder && ServiceEnabled(deploymentEnvironment); + } + + private bool ServiceEnabled(string deploymentEnvironment) + { + if (EnvironmentVariables == null) + { + return true; + } + return EnvironmentVariables.Any(o => o == deploymentEnvironment); } } } \ No newline at end of file diff --git a/Implem.ParameterAccessor/Parts/Service.cs b/Implem.ParameterAccessor/Parts/Service.cs index 8d0a0ac45..c92861ab9 100644 --- a/Implem.ParameterAccessor/Parts/Service.cs +++ b/Implem.ParameterAccessor/Parts/Service.cs @@ -6,11 +6,13 @@ public class Service public string EnvironmentName; public string TimeZoneDefault; public string DefaultPassword; + public string DeploymentEnvironment; public bool WithoutChangeDefaultPassword; public string DefaultLanguage; public string AbsoluteUri; public long MaxRequestBodySize; public bool RequireHttps; + public long AnnouncementSiteId; public bool ShowProfiles; public bool ShowChangePassword; public bool ShowStartGuide; diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Base_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Base_Body.txt index 3abf3fb6b..524c0e8d2 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Base_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Base_Body.txt @@ -52,6 +52,7 @@ namespace Implem.Pleasanter.Models public Dictionary SavedCheckHash = new Dictionary(); public Dictionary AttachmentsHash = new Dictionary(); public Dictionary SavedAttachmentsHash = new Dictionary(); + public Dictionary PostedImageHash = new Dictionary(); public bool ReadOnly; public List MineCache; [NonSerialized] diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Body.txt index 5c992b83f..095e845f5 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Body.txt @@ -123,6 +123,7 @@ namespace Implem.Pleasanter.Models + diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_CreatedNotice_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_CreatedNotice_Body.txt index 6e46807d5..caf40a7e3 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_CreatedNotice_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_CreatedNotice_Body.txt @@ -11,23 +11,25 @@ ss: ss, notice: notice), type: noticeType); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_OnUpdatedNotice_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_OnUpdatedNotice_Body.txt index 955b5df5d..3009f8229 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_OnUpdatedNotice_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_OnUpdatedNotice_Body.txt @@ -11,23 +11,25 @@ ss: ss, notice: notice)), type: "Updated"); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApiImages.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApiImages.json new file mode 100644 index 000000000..979122aad --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApiImages.json @@ -0,0 +1,5 @@ +{ + "Id": "Model_SetByApiImages", + "Indent": "2", + "Include": "Issues,Results" +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApiImages_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApiImages_Body.txt new file mode 100644 index 000000000..c74676d07 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApiImages_Body.txt @@ -0,0 +1,84 @@ +public void SetPostedFiles( + Microsoft.AspNetCore.Http.IFormFile file, + string columnName, + Shared._ImageApiModel image) +{ + PostedImageHash.Add( + columnName, + new PostedFile() + { + Guid = new HttpPostedFile(file).WriteToTemp(), + FileName = file.FileName.Split(System.IO.Path.DirectorySeparatorChar).Last(), + Extension = image.Extension, + Size = file.Length, + ContentType = MimeKit.MimeTypes.GetMimeType(image.Extension), + ContentRange = file.Length > 0 + ? new System.Net.Http.Headers.ContentRangeHeaderValue( + 0, + file.Length - 1, + file.Length) + : new System.Net.Http.Headers.ContentRangeHeaderValue(0, 0, 0), + InputStream = file.OpenReadStream() + }); +} + +public void SetImageValue( + Context context, + SiteSettings ss, + string columnName, + Shared._ImageApiModel imageApiModel) +{ + var imageText = $"![{imageApiModel.Alt}](/binaries/{PostedImageHash.Get(columnName).Guid}/show)"; + switch (columnName) + { + case "Body": + Body = InsertImageText( + body: Body, + imageText: imageText, + imageApiModel: imageApiModel); + break; + case "Comments": + var comment = Comments.GetCreated( + context: context, + ss: ss); + comment.Body = InsertImageText( + body: comment.Body, + imageText: imageText, + imageApiModel: imageApiModel); + break; + default: + if (Def.ExtendedColumnTypes.Get(columnName) == "Description") + { + if (!DescriptionHash.ContainsKey(columnName)) + { + DescriptionHash.Add(columnName, string.Empty); + } + DescriptionHash[columnName] = InsertImageText( + body: DescriptionHash.Get(columnName), + imageText: imageText, + imageApiModel: imageApiModel); + } + break; + } +} + +public string InsertImageText( + string body, + string imageText, + Shared._ImageApiModel imageApiModel) +{ + if (imageApiModel.HeadNewLine == true) + { + imageText = $"\n{imageText}"; + } + if (imageApiModel.EndNewLine == true) + { + imageText = $"{imageText}\n"; + } + var insertedBody = imageApiModel.Position.ToInt() == -1 + ? body + imageText + : imageApiModel.Position.ToInt() < body.Length + ? body.Insert(imageApiModel.Position.ToInt(), imageText) + : body + imageText; + return insertedBody; +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_Body.txt index 40eb39a59..ca9ae475c 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_Body.txt @@ -94,6 +94,7 @@ SetAttachments(columnName: columnName, value: newAttachments); }); + diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_ImageHash.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_ImageHash.json new file mode 100644 index 000000000..d57eee913 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_ImageHash.json @@ -0,0 +1,5 @@ +{ + "Id": "Model_SetByApi_ImageHash", + "Indent": "3", + "Include": "Issues,Results" +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_ImageHash_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_ImageHash_Body.txt new file mode 100644 index 000000000..3d44c2554 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByApi_ImageHash_Body.txt @@ -0,0 +1,18 @@ +data.ImageHash?.ForEach(o => +{ + var bytes = Convert.FromBase64String(o.Value.Base64); + var stream = new System.IO.MemoryStream(bytes); + var file = new Microsoft.AspNetCore.Http.FormFile(stream, 0, bytes.Length, null, $"image{o.Value.Extension}"); + if (ss.ColumnHash.Get(o.Key).AllowImage == true) + { + SetPostedFiles( + file: file, + columnName: o.Key, + image: o.Value); + SetImageValue( + context: context, + ss: ss, + columnName: o.Key, + imageApiModel: o.Value); + } +}); \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateTitles_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateTitles_Body.txt index 0b7e2e64c..cfb9bb179 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateTitles_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateTitles_Body.txt @@ -5,5 +5,6 @@ ItemUtilities.UpdateSourceTitles( context: context, ss: ss, + siteIdList: new List() { ss.SiteId }, idList: #ModelName#Id.ToSingleList()); } \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_BulkProcess_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_BulkProcess_Body.txt index 2fbce1179..3b49b3c86 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_BulkProcess_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_BulkProcess_Body.txt @@ -8,7 +8,7 @@ var process = ss.GetProcess( context: context, id: processId); - if (process == null) + if (process == null || !process.GetAllowBulkProcessing()) { return Messages.NotFound(context: context).ToJson(); } diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreateByApi_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreateByApi_Body.txt index d5da39c0c..e39f0f3ce 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreateByApi_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreateByApi_Body.txt @@ -33,6 +33,11 @@ context: context, ss: ss, notice: true); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: #modelName#Model.#ModelName#Id, + postedFileHash: #modelName#Model.PostedImageHash); switch (errorData.Type) { case Error.Types.None: diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreatedResponse_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreatedResponse_Body.txt index 6722a2201..9e0dbf8ce 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreatedResponse_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_CreatedResponse_Body.txt @@ -4,7 +4,7 @@ context: context, ss: ss, #modelName#Model: #modelName#Model, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: #modelName#Model.#ModelName#Id) diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_ItemTitle_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_ItemTitle_Body.txt index e1277079e..345b2bbf1 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_ItemTitle_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_ItemTitle_Body.txt @@ -1,42 +1,52 @@ -public static void UpdateSourceTitles(Context context, SiteSettings ss, IList idList) +public static void UpdateSourceTitles( + Context context, + SiteSettings ss, + IList siteIdList, + IList idList) { - ss.Sources - .ForEach(source => + ss.Sources.ForEach(source => + { + var currentSs = source.Value; + var columns = currentSs?.Links + ?.Where(o => o.SiteId > 0) + .Where(o => o.SiteId == ss.SiteId) + .Select(o => o.ColumnName) + .ToList(); + if (currentSs?.TitleColumns?.Any(o => columns?.Contains(o) == true) == true) { - var currentSs = source.Value; - var columns = currentSs?.Links - ?.Where(o => o.SiteId > 0) - .Where(o => o.SiteId == ss.SiteId) - .Select(o => o.ColumnName) - .ToList(); - if (currentSs?.TitleColumns?.Any(o => columns?.Contains(o) == true) == true) + currentSs.SetLinkedSiteSettings(context: context); + if (!siteIdList.Contains(currentSs.SiteId)) { - var nextIdList = - Repository.ExecuteTable( - context: context, - statements: Rds.SelectLinks( - column: Rds.LinksColumn() - .SourceId(), - join: Rds.LinksJoinDefault(), - where: Rds.LinksWhere() - .SiteId(currentSs.SiteId) - .DestinationId_In( - value: idList, - _using: idList.Count <= 100))) - .AsEnumerable() - .Select(dataRow => dataRow.Long("SourceId")) - .ToList(); - currentSs.SetLinkedSiteSettings(context: context); + siteIdList.Add(currentSs.SiteId); + var nextIdList = Repository.ExecuteTable( + context: context, + statements: Rds.SelectLinks( + column: Rds.LinksColumn() + .SourceId(), + join: Rds.LinksJoinDefault(), + where: Rds.LinksWhere() + .SiteId(currentSs.SiteId) + .DestinationId_In( + value: idList, + _using: idList.Count <= 100))) + .AsEnumerable() + .Select(dataRow => dataRow.Long("SourceId")) + .ToList(); UpdateTitles( context: context, ss: currentSs, + siteIdList: siteIdList, idList: nextIdList); } - }); + } + }); } public static void UpdateTitles( - Context context, SiteSettings ss, IList idList = null) + Context context, + SiteSettings ss, + IList siteIdList, + IList idList = null) { switch (ss?.ReferenceType) { diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_Body.txt index dce09e8d1..2ce88974e 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_Body.txt @@ -1,5 +1,8 @@ private static void Update#ModelName#Titles( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList siteIdList, + IList idList) { var #tableName# = Get#TableName#( context: context, @@ -38,12 +41,15 @@ UpdateSourceTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: #tableName#.Select(o => o.#ModelName#Id).ToList()); } } private static List<#ModelName#Model> Get#TableName#( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList idList) { var column = Rds.#TableName#Column() .#ModelName#Id() diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_TableCases_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_TableCases_Body.txt index 42750bc07..064b3ea86 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_TableCases_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_SetItemTitle_TableCases_Body.txt @@ -2,5 +2,6 @@ Update#ModelName#Titles( context: context, ss: ss, + siteIdList: siteIdList, idList: idList); break; \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdateByApi_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdateByApi_Body.txt index bb61e6a0b..b0198d30c 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdateByApi_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdateByApi_Body.txt @@ -42,6 +42,11 @@ ss: ss, notice: true, previousTitle: previousTitle); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: #modelName#Model.#ModelName#Id, + postedFileHash: #modelName#Model.PostedImageHash); switch (errorData.Type) { case Error.Types.None: diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdatedMessage_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdatedMessage_Body.txt index 4abc0ea02..b9bfac06c 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdatedMessage_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpdatedMessage_Body.txt @@ -4,7 +4,9 @@ #ModelName#Model #modelName#Model, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpsertByApi_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpsertByApi_Body.txt index 14ef02cd9..453be0606 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpsertByApi_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_UpsertByApi_Body.txt @@ -76,6 +76,11 @@ ss: ss, notice: true, previousTitle: previousTitle); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: #modelName#Model.#ModelName#Id, + postedFileHash: #modelName#Model.PostedImageHash); switch (errorData.Type) { case Error.Types.None: diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_Body.txt index 2d168391f..c41e3b2d0 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_Body.txt @@ -7,6 +7,7 @@ ss.Init(context: context); + return ss; } \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_Users.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_Users.json new file mode 100644 index 000000000..a2ffeba26 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_Users.json @@ -0,0 +1,7 @@ +{ + "Id": "SiteSettings_Users", + "Indent": "3", + "Separator": "\\r\\n", + "NotItem": "1", + "Include": "Users" +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_Users_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_Users_Body.txt new file mode 100644 index 000000000..233e11c85 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_Users_Body.txt @@ -0,0 +1,18 @@ +if (!DefinitionAccessor.Parameters.User.DisableApi && !context.DisableApi) +{ + var column = ss.GetColumn( + context: context, + columnName: "AllowApi"); + var columnAccessControl = new ColumnAccessControl() + { + No = column.No, + ColumnName = column.ColumnName, + Type = Permissions.Types.ManageService + }; + ss.CreateColumnAccessControls = ss.CreateColumnAccessControls ?? new List(); + ss.ReadColumnAccessControls = ss.ReadColumnAccessControls ?? new List(); + ss.UpdateColumnAccessControls = ss.UpdateColumnAccessControls ?? new List(); + ss.CreateColumnAccessControls.Add(columnAccessControl); + ss.ReadColumnAccessControls.Add(columnAccessControl); + ss.UpdateColumnAccessControls.Add(columnAccessControl); +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableApi.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableApi.json new file mode 100644 index 000000000..2d2061627 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableApi.json @@ -0,0 +1,18 @@ +{ + "Id": "Tenants_DisableApi", + "ModelName": "Tenant", + "TableName": "Tenants", + "Label": "テナント", + "ColumnName": "DisableApi", + "LabelText": "APIを無効化", + "No": "107", + "History": "107", + "TypeName": "bit", + "Nullable": "1", + "LabelText_en": "Disable api", + "LabelText_zh": "禁用 api", + "LabelText_de": "API deaktivieren", + "LabelText_ko": "API 비활성화", + "LabelText_es": "Deshabilitar API", + "LabelText_vn": "Tắt api" +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableStartGuide.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableStartGuide.json index a38946134..4123e2b22 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableStartGuide.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_DisableStartGuide.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "DisableStartGuide", "LabelText": "スタートガイドを使用しない", - "No": "107", - "History": "107", + "No": "108", + "History": "108", "TypeName": "bit", "Nullable": "1", "LabelText_en": "Disable start guide", diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleRecord.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleRecord.json index 78d906058..2c194fbf9 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleRecord.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleRecord.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "HtmlTitleRecord", "LabelText": "レコード", - "No": "111", - "History": "111", + "No": "112", + "History": "112", "TypeName": "nvarchar", "MaxLength": "1024", "Default": "[ProductName]", diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleSite.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleSite.json index 9778f7dd4..86b9ce48d 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleSite.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleSite.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "HtmlTitleSite", "LabelText": "サイト", - "No": "110", - "History": "110", + "No": "111", + "History": "111", "TypeName": "nvarchar", "MaxLength": "1024", "Default": "[ProductName]", diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleTop.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleTop.json index b8b3c0505..b9d0b8c39 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleTop.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_HtmlTitleTop.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "HtmlTitleTop", "LabelText": "トップ", - "No": "109", - "History": "109", + "No": "110", + "History": "110", "TypeName": "nvarchar", "MaxLength": "1024", "Default": "[ProductName]", diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_LogoType.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_LogoType.json index af56dd930..0944f142f 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_LogoType.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_LogoType.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "LogoType", "LabelText": "ロゴ画像タイプ", - "No": "108", - "History": "108", + "No": "109", + "History": "109", "TypeName": "int", "TypeCs": "LogoTypes", "RecordingData": ".ToInt()", diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopScript.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopScript.json index 0707aa975..a576bf381 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopScript.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopScript.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "TopScript", "LabelText": "トップのスクリプト", - "No": "113", - "History": "113", + "No": "114", + "History": "114", "TypeName": "nvarchar", "MaxLength": "-1", "Nullable": "1", diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopStyle.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopStyle.json index ecbe1d01f..85f273fa1 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopStyle.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Tenants_TopStyle.json @@ -5,8 +5,8 @@ "Label": "テナント", "ColumnName": "TopStyle", "LabelText": "トップのスタイル", - "No": "112", - "History": "112", + "No": "113", + "History": "113", "TypeName": "nvarchar", "MaxLength": "-1", "Nullable": "1", diff --git a/Implem.Pleasanter/App_Data/Parameters/BackgroundService.json b/Implem.Pleasanter/App_Data/Parameters/BackgroundService.json index ccf42b573..d9e97e0da 100644 --- a/Implem.Pleasanter/App_Data/Parameters/BackgroundService.json +++ b/Implem.Pleasanter/App_Data/Parameters/BackgroundService.json @@ -1,4 +1,5 @@ { + "EnvironmentVariables": null, "Reminder": false, "ReminderIgnoreConsecutiveExceptionCount": 30, "SyncByLdap": false, diff --git a/Implem.Pleasanter/App_Data/Parameters/Service.json b/Implem.Pleasanter/App_Data/Parameters/Service.json index 192316551..733bc23b2 100644 --- a/Implem.Pleasanter/App_Data/Parameters/Service.json +++ b/Implem.Pleasanter/App_Data/Parameters/Service.json @@ -2,11 +2,13 @@ "Name": "Implem.Pleasanter", "TimeZoneDefault": "Asia/Tokyo", "DefaultPassword": "pleasanter", + "DeploymentEnvironment": null, "WithoutChangeDefaultPassword": false, "DefaultLanguage": "ja", "AbsoluteUri": null, "MaxRequestBodySize": 30000000, "RequireHttps": false, + "AnnouncementSiteId": 0, "ShowProfiles": true, "ShowChangePassword": false, "ShowStartGuide": true, diff --git a/Implem.Pleasanter/Implem.Pleasanter.csproj b/Implem.Pleasanter/Implem.Pleasanter.csproj index e952691db..a76b5f731 100644 --- a/Implem.Pleasanter/Implem.Pleasanter.csproj +++ b/Implem.Pleasanter/Implem.Pleasanter.csproj @@ -5,10 +5,10 @@ Copyright © Implem Inc 2014 - 2022 Business application platform Implem.Pleasanter - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 7.2 - 1.3.25.3 + 1.3.26.0 disable Linux ..\docker-compose.dcproj diff --git a/Implem.Pleasanter/Libraries/BackgroundServices/ReminderBackgroundService.cs b/Implem.Pleasanter/Libraries/BackgroundServices/ReminderBackgroundService.cs index 69cf57520..a3afe686c 100644 --- a/Implem.Pleasanter/Libraries/BackgroundServices/ReminderBackgroundService.cs +++ b/Implem.Pleasanter/Libraries/BackgroundServices/ReminderBackgroundService.cs @@ -22,6 +22,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) sessionData: false, user: false, item: false); + new SysLogModel( + context: context, + method: nameof(ExecuteAsync), + message: "ReminderBackgroundService ExecuteAsync() Started", + sysLogType: SysLogModel.SysLogTypes.Info); var exceptionCount = 0; while (!stoppingToken.IsCancellationRequested) { @@ -35,7 +40,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) new SysLogModel( context: context, e: e, - extendedErrorMessage: "Reminder Canceled"); + extendedErrorMessage: "ReminderBackgroundService Canceled"); break; } catch (Exception e) @@ -44,7 +49,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) new SysLogModel( context: context, e: e, - extendedErrorMessage: $"Reminder Exception Count={exceptionCount}"); + extendedErrorMessage: $"ReminderBackgroundService Exception Count={exceptionCount}"); if (exceptionCount > Parameters.BackgroundService.ReminderIgnoreConsecutiveExceptionCount) { throw; @@ -52,6 +57,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); } } + new SysLogModel( + context: context, + method: nameof(ExecuteAsync), + message: "ReminderBackgroundService ExecuteAsync() Stopped", + sysLogType: SysLogModel.SysLogTypes.Info); } } } diff --git a/Implem.Pleasanter/Libraries/BackgroundServices/TimerBackgroundService.cs b/Implem.Pleasanter/Libraries/BackgroundServices/TimerBackgroundService.cs index 89c2c8023..8318121d2 100644 --- a/Implem.Pleasanter/Libraries/BackgroundServices/TimerBackgroundService.cs +++ b/Implem.Pleasanter/Libraries/BackgroundServices/TimerBackgroundService.cs @@ -140,6 +140,11 @@ public async Task WaitNextTimerThenExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken) { var context = CreateContext(); + new SysLogModel( + context: context, + method: nameof(ExecuteAsync), + message: "TimerBackgroundService ExecuteAsync() Started", + sysLogType: SysLogModel.SysLogTypes.Info); while (!stoppingToken.IsCancellationRequested) { try @@ -165,7 +170,7 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) new SysLogModel( context: context, method: nameof(ExecuteAsync), - message: "ExecuteAsync() Canceled", + message: "TimerBackgroundService ExecuteAsync() Stopped", sysLogType: SysLogModel.SysLogTypes.Info); } } diff --git a/Implem.Pleasanter/Libraries/DataSources/Rds.cs b/Implem.Pleasanter/Libraries/DataSources/Rds.cs index 460c41120..79616029f 100644 --- a/Implem.Pleasanter/Libraries/DataSources/Rds.cs +++ b/Implem.Pleasanter/Libraries/DataSources/Rds.cs @@ -1426,6 +1426,7 @@ public static string ColumnBracket(Column column) case "ContractSettings": return "\"ContractSettings\""; case "ContractDeadline": return "\"ContractDeadline\""; case "DisableAllUsersPermission": return "\"DisableAllUsersPermission\""; + case "DisableApi": return "\"DisableApi\""; case "DisableStartGuide": return "\"DisableStartGuide\""; case "LogoType": return "\"LogoType\""; case "HtmlTitleTop": return "\"HtmlTitleTop\""; @@ -3752,6 +3753,12 @@ public static SqlOrderByCollection Add( orderType: orderType, isNullValue: isNullValue, function: function); + case "DisableApi": + return self.Tenants_DisableApi( + tableName: column.TableName(), + orderType: orderType, + isNullValue: isNullValue, + function: function); case "DisableStartGuide": return self.Tenants_DisableStartGuide( tableName: column.TableName(), @@ -11662,6 +11669,7 @@ public static SqlStatement TenantsCopyToStatement(SqlWhereCollection where, Sqls column.ContractSettings(function: Sqls.Functions.SingleColumn); param.ContractSettings(); column.ContractDeadline(function: Sqls.Functions.SingleColumn); param.ContractDeadline(); column.DisableAllUsersPermission(function: Sqls.Functions.SingleColumn); param.DisableAllUsersPermission(); + column.DisableApi(function: Sqls.Functions.SingleColumn); param.DisableApi(); column.DisableStartGuide(function: Sqls.Functions.SingleColumn); param.DisableStartGuide(); column.LogoType(function: Sqls.Functions.SingleColumn); param.LogoType(); column.HtmlTitleTop(function: Sqls.Functions.SingleColumn); param.HtmlTitleTop(); @@ -14851,6 +14859,7 @@ insert into ""Tenants_deleted"" ""ContractSettings"", ""ContractDeadline"", ""DisableAllUsersPermission"", + ""DisableApi"", ""DisableStartGuide"", ""LogoType"", ""HtmlTitleTop"", @@ -14875,6 +14884,7 @@ insert into ""Tenants_deleted"" ""Tenants"".""ContractSettings"", ""Tenants"".""ContractDeadline"", ""Tenants"".""DisableAllUsersPermission"", + ""Tenants"".""DisableApi"", ""Tenants"".""DisableStartGuide"", ""Tenants"".""LogoType"", ""Tenants"".""HtmlTitleTop"", @@ -16214,6 +16224,7 @@ insert into ""Tenants"" ""ContractSettings"", ""ContractDeadline"", ""DisableAllUsersPermission"", + ""DisableApi"", ""DisableStartGuide"", ""LogoType"", ""HtmlTitleTop"", @@ -16238,6 +16249,7 @@ insert into ""Tenants"" ""Tenants_deleted"".""ContractSettings"", ""Tenants_deleted"".""ContractDeadline"", ""Tenants_deleted"".""DisableAllUsersPermission"", + ""Tenants_deleted"".""DisableApi"", ""Tenants_deleted"".""DisableStartGuide"", ""Tenants_deleted"".""LogoType"", ""Tenants_deleted"".""HtmlTitleTop"", @@ -85410,6 +85422,8 @@ public static TenantsColumnCollection TenantsColumn( return self.ContractDeadline(_as: _as, function: function); case "DisableAllUsersPermission": return self.DisableAllUsersPermission(_as: _as, function: function); + case "DisableApi": + return self.DisableApi(_as: _as, function: function); case "DisableStartGuide": return self.DisableStartGuide(_as: _as, function: function); case "LogoType": @@ -85717,6 +85731,40 @@ public static SqlColumnCollection Tenants_DisableAllUsersPermission( sub: sub); } + public static TenantsColumnCollection DisableApi( + this TenantsColumnCollection self, + string tableName = "Tenants", + string columnName = "DisableApi", + string _as = null, + Sqls.Functions function = Sqls.Functions.None, + SqlStatement sub = null) + { + return self.Add( + columnBracket: "\"DisableApi\"", + tableName: tableName, + columnName: columnName, + _as: _as, + function: function, + sub: sub); + } + + public static SqlColumnCollection Tenants_DisableApi( + this SqlColumnCollection self, + string tableName = "Tenants", + string columnName = "DisableApi", + string _as = null, + Sqls.Functions function = Sqls.Functions.None, + SqlStatement sub = null) + { + return self.Add( + columnBracket: "\"DisableApi\"", + tableName: tableName, + columnName: columnName, + _as: _as, + function: function, + sub: sub); + } + public static TenantsColumnCollection DisableStartGuide( this TenantsColumnCollection self, string tableName = "Tenants", @@ -86600,6 +86648,64 @@ public static SqlWhereCollection Tenants_DisableAllUsersPermission( : self; } + public static TenantsWhereCollection DisableApi( + this TenantsWhereCollection self, + object value = null, + string tableName = "Tenants", + string _operator = "=", + string multiColumnOperator = " or ", + string multiParamOperator = " and ", + SqlStatement subLeft = null, + SqlStatement sub = null, + bool subPrefix = true, + string raw = null, + bool _using = true) + { + return _using + ? self.Add( + columnBrackets: new string[] { "\"DisableApi\"" }, + tableName: tableName, + name: "DisableApi", + value: value, + _operator: _operator, + multiColumnOperator: multiColumnOperator, + multiParamOperator: multiParamOperator, + subLeft: subLeft, + sub: sub, + subPrefix: subPrefix, + raw: raw) + : self; + } + + public static SqlWhereCollection Tenants_DisableApi( + this SqlWhereCollection self, + object value = null, + string tableName = "Tenants", + string _operator = "=", + string multiColumnOperator = " or ", + string multiParamOperator = " and ", + SqlStatement subLeft = null, + SqlStatement sub = null, + bool subPrefix = true, + string raw = null, + bool _using = true) + { + return _using + ? self.Add( + columnBrackets: new string[] { "\"DisableApi\"" }, + tableName: tableName, + name: "DisableApi", + value: value, + _operator: _operator, + multiColumnOperator: multiColumnOperator, + multiParamOperator: multiParamOperator, + subLeft: subLeft, + sub: sub, + subPrefix: subPrefix, + raw: raw) + : self; + } + public static TenantsWhereCollection DisableStartGuide( this TenantsWhereCollection self, object value = null, @@ -87786,6 +87892,7 @@ public static TenantsGroupByCollection TenantsGroupBy( case "ContractSettings": return self.ContractSettings(); case "ContractDeadline": return self.ContractDeadline(); case "DisableAllUsersPermission": return self.DisableAllUsersPermission(); + case "DisableApi": return self.DisableApi(); case "DisableStartGuide": return self.DisableStartGuide(); case "LogoType": return self.LogoType(); case "HtmlTitleTop": return self.HtmlTitleTop(); @@ -87906,6 +88013,18 @@ public static SqlGroupByCollection Tenants_DisableAllUsersPermission( return self.Add(columnBracket: "\"DisableAllUsersPermission\"", tableName: tableName); } + public static TenantsGroupByCollection DisableApi( + this TenantsGroupByCollection self, string tableName = "Tenants") + { + return self.Add(columnBracket: "\"DisableApi\"", tableName: tableName); + } + + public static SqlGroupByCollection Tenants_DisableApi( + this SqlGroupByCollection self, string tableName = "Tenants") + { + return self.Add(columnBracket: "\"DisableApi\"", tableName: tableName); + } + public static TenantsGroupByCollection DisableStartGuide( this TenantsGroupByCollection self, string tableName = "Tenants") { @@ -88230,6 +88349,23 @@ public static TenantsOrderByCollection DisableAllUsersPermission( return self; } + public static TenantsOrderByCollection DisableApi( + this TenantsOrderByCollection self, + SqlOrderBy.Types orderType = SqlOrderBy.Types.asc, + string tableName = "Tenants", + string isNullValue = null, + Sqls.Functions function = Sqls.Functions.None) + { + new List { "\"DisableApi\"" }.ForEach(columnBracket => + self.Add( + columnBracket: columnBracket, + orderType: orderType, + tableName: tableName, + isNullValue: isNullValue, + function: function)); + return self; + } + public static TenantsOrderByCollection DisableStartGuide( this TenantsOrderByCollection self, SqlOrderBy.Types orderType = SqlOrderBy.Types.asc, @@ -88570,6 +88706,23 @@ public static SqlOrderByCollection Tenants_DisableAllUsersPermission( return self; } + public static SqlOrderByCollection Tenants_DisableApi( + this SqlOrderByCollection self, + SqlOrderBy.Types orderType = SqlOrderBy.Types.asc, + string tableName = "Tenants", + string isNullValue = null, + Sqls.Functions function = Sqls.Functions.None) + { + new List { "\"DisableApi\"" }.ForEach(columnBracket => + self.Add( + columnBracket: columnBracket, + orderType: orderType, + tableName: tableName, + isNullValue: isNullValue, + function: function)); + return self; + } + public static SqlOrderByCollection Tenants_DisableStartGuide( this SqlOrderByCollection self, SqlOrderBy.Types orderType = SqlOrderBy.Types.asc, @@ -89056,6 +89209,40 @@ public static SqlParamCollection Tenants_DisableAllUsersPermission( : self; } + public static TenantsParamCollection DisableApi( + this TenantsParamCollection self, + object value = null, + SqlStatement sub = null, + string raw = null, + bool _using = true) + { + return _using + ? self.Add( + columnBracket: "\"DisableApi\"", + name: "DisableApi", + value: value, + sub: sub, + raw: raw) + : self; + } + + public static SqlParamCollection Tenants_DisableApi( + this SqlParamCollection self, + object value = null, + SqlStatement sub = null, + string raw = null, + bool _using = true) + { + return _using + ? self.Add( + columnBracket: "\"DisableApi\"", + name: "DisableApi", + value: value, + sub: sub, + raw: raw) + : self; + } + public static TenantsParamCollection DisableStartGuide( this TenantsParamCollection self, object value = null, @@ -117064,6 +117251,7 @@ public static TenantsColumnCollection TenantsDefaultColumns() .ContractSettings() .ContractDeadline() .DisableAllUsersPermission() + .DisableApi() .DisableStartGuide() .LogoType() .HtmlTitleTop() @@ -117112,6 +117300,7 @@ public static TenantsParamCollection TenantsParamDefault( .ContractSettings(tenantModel.ContractSettings?.RecordingJson(), _using: tenantModel.ContractSettings_Updated(context) || (otherInitValue && !tenantModel.ContractSettings.InitialValue(context))) .ContractDeadline(tenantModel.ContractDeadline, _using: tenantModel.ContractDeadline_Updated(context) || (otherInitValue && !tenantModel.ContractDeadline.InitialValue(context))) .DisableAllUsersPermission(tenantModel.DisableAllUsersPermission, _using: tenantModel.DisableAllUsersPermission_Updated(context) || (otherInitValue && !tenantModel.DisableAllUsersPermission.InitialValue(context))) + .DisableApi(tenantModel.DisableApi, _using: tenantModel.DisableApi_Updated(context) || (otherInitValue && !tenantModel.DisableApi.InitialValue(context))) .DisableStartGuide(tenantModel.DisableStartGuide, _using: tenantModel.DisableStartGuide_Updated(context) || (otherInitValue && !tenantModel.DisableStartGuide.InitialValue(context))) .LogoType(tenantModel.LogoType.ToInt(), _using: tenantModel.LogoType_Updated(context) || setDefault || (otherInitValue && !tenantModel.LogoType.InitialValue(context))) .HtmlTitleTop(tenantModel.HtmlTitleTop.MaxLength(1024), _using: tenantModel.HtmlTitleTop_Updated(context) || setDefault || (otherInitValue && !tenantModel.HtmlTitleTop.InitialValue(context))) diff --git a/Implem.Pleasanter/Libraries/DataSources/Saml.cs b/Implem.Pleasanter/Libraries/DataSources/Saml.cs index 0254fbe50..2e18dd5e8 100644 --- a/Implem.Pleasanter/Libraries/DataSources/Saml.cs +++ b/Implem.Pleasanter/Libraries/DataSources/Saml.cs @@ -340,7 +340,7 @@ public static void SetSPOptions(Saml2Options options) { options.Notifications.SelectIdentityProvider = (entityId, rd) => { - return GetSamlIdp(entityId, rd); + return GetSamlIdp(entityId, rd) ?? options.IdentityProviders.Default; }; options.Notifications.GetIdentityProvider = (entityId, rd, op) => { @@ -349,13 +349,13 @@ public static void SetSPOptions(Saml2Options options) } } - private static Sustainsys.Saml2.IdentityProvider GetSamlIdp(EntityId entityId, IDictionary rd) + private static Sustainsys.Saml2.IdentityProvider GetSamlIdp(EntityId entityId, IDictionary rd) { if (entityId == null) { return null; } - if (!rd.TryGetValue("SignOnUrl",out string signOnUrl)) + if (rd?.TryGetValue("SignOnUrl", out string signOnUrl) != true) { return null; } diff --git a/Implem.Pleasanter/Libraries/DataTypes/Comments.cs b/Implem.Pleasanter/Libraries/DataTypes/Comments.cs index 997fd3335..798943233 100644 --- a/Implem.Pleasanter/Libraries/DataTypes/Comments.cs +++ b/Implem.Pleasanter/Libraries/DataTypes/Comments.cs @@ -161,9 +161,13 @@ public bool InitialValue(Context context) return this?.Any() != true; } - public Comments Prepend(Context context, SiteSettings ss, string body) + public Comments Prepend( + Context context, + SiteSettings ss, + string body, + bool force = false) { - if (body.Trim() != string.Empty) + if (body.Trim() != string.Empty || force == true) { Insert(0, new Comment { @@ -177,6 +181,19 @@ public Comments Prepend(Context context, SiteSettings ss, string body) return this; } + public Comment GetCreated(Context context, SiteSettings ss) + { + if (!this.Any(comment => comment.Created)) + { + Prepend( + context: context, + ss: ss, + body: string.Empty, + force: true); + } + return this.FirstOrDefault(comment => comment.Created); + } + public void Update(Context context, SiteSettings ss, int commentId, string body) { this.FirstOrDefault(o => o.CommentId == commentId)? diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlControls.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlControls.cs index b822fa01e..7d1ef92e4 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlControls.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlControls.cs @@ -609,7 +609,11 @@ public static HtmlBuilder CheckBox( hb.Span(css: $"ui-icon {labelIcon}"); } hb.Label( - attributes: new HtmlAttributes().For(controlId), + attributes: new HtmlAttributes() + .For(controlId) + .Class(validateRequired + ? " required" + : string.Empty), action: () => hb .Text(text: labelText)); } diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlFields.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlFields.cs index cd84388b5..c28243e94 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlFields.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlFields.cs @@ -404,7 +404,6 @@ private static HtmlBuilder SwitchField( _checked: value.ToBool(), disabled: true, alwaysSend: alwaysSend, - validateRequired: required, extendedHtmlBeforeLabel: extendedHtmlBeforeLabel, extendedHtmlBetweenLabelAndControl: extendedHtmlBetweenLabelAndControl, extendedHtmlAfterControl: extendedHtmlAfterControl); @@ -428,7 +427,6 @@ private static HtmlBuilder SwitchField( allowImage: column.AllowImage == true, mobile: mobile, alwaysSend: alwaysSend, - validateRequired: required, preview: preview, validateMaxLength: column.MaxLength.ToInt(), validateRegex: column.ClientRegexValidation, diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlHeaders.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlHeaders.cs index 2f22543a2..a7971eecb 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlHeaders.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlHeaders.cs @@ -2,11 +2,14 @@ using Implem.Libraries.Utilities; using Implem.Pleasanter.Libraries.General; using Implem.Pleasanter.Libraries.Html; +using Implem.Pleasanter.Libraries.DataSources; using Implem.Pleasanter.Libraries.Requests; using Implem.Pleasanter.Libraries.Responses; using Implem.Pleasanter.Libraries.Settings; using Implem.Pleasanter.Models; using static Implem.Pleasanter.Libraries.ServerScripts.ServerScriptModel; +using System; + namespace Implem.Pleasanter.Libraries.HtmlParts { public static class HtmlHeaders @@ -23,6 +26,7 @@ public static HtmlBuilder Header( ServerScriptModelRow serverScriptModelRow) { return hb.Header(id: "Header", action: () => hb + .Announcement() .HeaderLogo( context: context, ss: ss) @@ -37,6 +41,36 @@ public static HtmlBuilder Header( serverScriptModelRow: serverScriptModelRow)); } + public static HtmlBuilder Announcement(this HtmlBuilder hb) + { + var siteId = Parameters.Service.AnnouncementSiteId; + if (siteId > 0) + { + var context = new Context( + sessionStatus: false, + sessionData: false, + item: false, + setPermissions: false); + var ss = SiteSettingsUtilities.Get( + context: context, + siteId: siteId); + var now = DateTime.Now; + var issueCollection = new IssueCollection( + context: context, + ss: ss, + where: Rds.IssuesWhere() + .SiteId(Parameters.Service.AnnouncementSiteId) + .Status(_operator: $"<{Parameters.General.CompletionCode}") + .StartTime(now, _operator: "<=") + .CompletionTime(now, _operator: ">=")); + foreach (var issueModel in issueCollection) + { + hb.Raw(text: issueModel.Body); + } + } + return hb; + } + public static HtmlBuilder HeaderLogo( this HtmlBuilder hb, Context context, diff --git a/Implem.Pleasanter/Libraries/Requests/Context.cs b/Implem.Pleasanter/Libraries/Requests/Context.cs index ad9c3ded4..1a0e27b68 100644 --- a/Implem.Pleasanter/Libraries/Requests/Context.cs +++ b/Implem.Pleasanter/Libraries/Requests/Context.cs @@ -77,6 +77,7 @@ public class Context : ISqlObjectFactory public string SiteTitle { get; set; } public string RecordTitle { get; set; } public bool DisableAllUsersPermission { get; set; } + public bool DisableApi { get; set; } public bool DisableStartGuide { get; set; } public string HtmlTitleTop { get; set; } public string HtmlTitleSite { get; set; } @@ -452,6 +453,7 @@ private void SetTenantProperties() .ContractDeadline() .LogoType() .DisableAllUsersPermission() + .DisableApi() .DisableStartGuide() .HtmlTitleTop() .HtmlTitleSite() @@ -469,6 +471,7 @@ private void SetTenantProperties() ContractSettings.Deadline = dataRow?.DateTime("ContractDeadline"); LogoType = (TenantModel.LogoTypes)dataRow.Int("LogoType"); DisableAllUsersPermission = dataRow.Bool("DisableAllUsersPermission"); + DisableApi = dataRow.Bool("DisableApi"); DisableStartGuide = dataRow.Bool("DisableStartGuide"); HtmlTitleTop = dataRow.String("HtmlTitleTop"); HtmlTitleSite = dataRow.String("HtmlTitleSite"); diff --git a/Implem.Pleasanter/Libraries/Responses/Displays.cs b/Implem.Pleasanter/Libraries/Responses/Displays.cs index 986cab774..5fc16e6b2 100644 --- a/Implem.Pleasanter/Libraries/Responses/Displays.cs +++ b/Implem.Pleasanter/Libraries/Responses/Displays.cs @@ -12179,6 +12179,16 @@ public static string Tenants_DisableAllUsersPermission( data: data); } + public static string Tenants_DisableApi( + Context context, + params string[] data) + { + return Get( + context: context, + id: "Tenants_DisableApi", + data: data); + } + public static string Tenants_DisableStartGuide( Context context, params string[] data) diff --git a/Implem.Pleasanter/Libraries/Responses/FileContentResults.cs b/Implem.Pleasanter/Libraries/Responses/FileContentResults.cs index 3de89320f..08b8a2334 100644 --- a/Implem.Pleasanter/Libraries/Responses/FileContentResults.cs +++ b/Implem.Pleasanter/Libraries/Responses/FileContentResults.cs @@ -143,7 +143,8 @@ private static DataRow GetBinariesTable(Context context, string guid) .CanRead( context: context, idColumnBracket: "\"Binaries\".\"ReferenceId\"", - _using: !context.Publish)), + _using: !context.Publish + && !RefererIsTenantManagement(context: context))), Rds.SelectBinaries( column: Rds.BinariesColumn() .BinaryId() @@ -178,6 +179,22 @@ private static DataRow GetBinariesTable(Context context, string guid) .FirstOrDefault(); } + public static bool RefererIsTenantManagement(Context context) + { + if (!context.UrlReferrer.IsNullOrEmpty()) + { + var url = new UriBuilder(context.UrlReferrer); + var ret = url.Path.Contains("/tenants") + || url.Path.Contains("/syslogs") + || url.Path.Contains("/depts") + || url.Path.Contains("/groups") + || url.Path.Contains("/users") + || url.Path.Contains("/registrations"); + return ret; + } + return false; + } + private static ResponseFile Bytes(DataRow dataRow, bool thumbnail = false) { var isThumbnail = thumbnail && dataRow["Thumbnail"] != DBNull.Value; diff --git a/Implem.Pleasanter/Libraries/Server/SiteInfo.cs b/Implem.Pleasanter/Libraries/Server/SiteInfo.cs index f97fdbf02..271283060 100644 --- a/Implem.Pleasanter/Libraries/Server/SiteInfo.cs +++ b/Implem.Pleasanter/Libraries/Server/SiteInfo.cs @@ -477,7 +477,7 @@ public static Dictionary Sites(Context context) public static LinkKeyValues Links(Context context) { - return TenantCaches.Get(context.TenantId).Links; + return TenantCaches.Get(context.TenantId)?.Links; } private static void SetSites(Context context, TenantCache tenantCache) diff --git a/Implem.Pleasanter/Libraries/Settings/Process.cs b/Implem.Pleasanter/Libraries/Settings/Process.cs index 1b66ff741..442b198a1 100644 --- a/Implem.Pleasanter/Libraries/Settings/Process.cs +++ b/Implem.Pleasanter/Libraries/Settings/Process.cs @@ -378,6 +378,13 @@ public bool Accessable(Context context, SiteSettings ss) return false; } + public bool GetAllowBulkProcessing() + { + return AllowBulkProcessing == true + && ValidateInputs?.Any(validationInput => + !validationInput.HasNotInputValidation()) != true; + } + public Message GetSuccessMessage(Context context) { var displayName = GetDisplayName(); diff --git a/Implem.Pleasanter/Libraries/Settings/Reminder.cs b/Implem.Pleasanter/Libraries/Settings/Reminder.cs index f8186010e..2b540ab30 100644 --- a/Implem.Pleasanter/Libraries/Settings/Reminder.cs +++ b/Implem.Pleasanter/Libraries/Settings/Reminder.cs @@ -513,6 +513,7 @@ private DataTable GetDataTable( var orderByColumn = ss.GetColumn( context: context, columnName: Column); + var convertedScheduledTime = scheduledTime.ToDateTime().ToUniversal(context: context).ToString("yyyy/M/d H:m:s.fff"); var column = new SqlColumnCollection() .Add(column: ss.GetColumn( context: context, @@ -551,9 +552,13 @@ private DataTable GetDataTable( tableName: ss.ReferenceType, columnBrackets: new string[] { - "\"" + orderByColumn.ColumnName + "\"" + orderByColumn.ColumnName == "CompletionTime" || ContainsTimeSettings(orderByColumn) + ? "\"" + orderByColumn.ColumnName + "\"" + : context.Sqls.DateAddDay(1, orderByColumn.ColumnName) }, - _operator: $">'{scheduledTime.ToDateTime().ToUniversal(context: context).ToString("yyyy/M/d H:m:s.fff")}'", + _operator: ContainsTimeSettings(orderByColumn) + ? $">='{convertedScheduledTime}'" + : $">'{convertedScheduledTime}'", _using: ExcludeOverdue == true) .Add(or: new SqlWhereCollection() .Add( @@ -602,6 +607,11 @@ private DataTable GetDataTable( return dataTable; } + private bool ContainsTimeSettings(Column column) + { + return column.EditorFormat == "Ymdhm" || column.EditorFormat == "Ymdhms"; + } + private string Relative(Context context, DateTime time) { var diff = DateTime.Now.ToLocal(context: context).Date - time; diff --git a/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs b/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs index 7aefa2134..a6e48f138 100644 --- a/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs +++ b/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs @@ -2914,7 +2914,7 @@ public Dictionary BulkProcessingItems(Context context, Site ?.Where(process => process.Accessable( context: context, ss: ss)) - .Where(process => process.AllowBulkProcessing == true) + .Where(process => process.GetAllowBulkProcessing()) .ToDictionary( process => process.Id.ToString(), process => new ControlData(process.GetDisplayName())); @@ -5253,7 +5253,10 @@ public bool CheckRow(Context context, List gridColumns) ? false : context.CanUpdate(ss: this) || context.CanDelete(ss: this) - || context.CanExport(ss: this); + || context.CanExport(ss: this) + || GetProcess( + context: context, + id: context.Forms.Int("BulkProcessingItems")) != null; } public bool GridColumnsHasSources(List gridColumns) diff --git a/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs b/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs index e9e580b02..e7f74c626 100644 --- a/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs +++ b/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs @@ -372,6 +372,24 @@ public static SiteSettings UsersSiteSettings(Context context) ss.SetLinks(context: context); ss.SetChoiceHash(context: context, withLink: false); ss.PermissionType = Permissions.Admins(context: context); + if (!DefinitionAccessor.Parameters.User.DisableApi && !context.DisableApi) + { + var column = ss.GetColumn( + context: context, + columnName: "AllowApi"); + var columnAccessControl = new ColumnAccessControl() + { + No = column.No, + ColumnName = column.ColumnName, + Type = Permissions.Types.ManageService + }; + ss.CreateColumnAccessControls = ss.CreateColumnAccessControls ?? new List(); + ss.ReadColumnAccessControls = ss.ReadColumnAccessControls ?? new List(); + ss.UpdateColumnAccessControls = ss.UpdateColumnAccessControls ?? new List(); + ss.CreateColumnAccessControls.Add(columnAccessControl); + ss.ReadColumnAccessControls.Add(columnAccessControl); + ss.UpdateColumnAccessControls.Add(columnAccessControl); + } return ss; } diff --git a/Implem.Pleasanter/Libraries/Settings/UserSettings.cs b/Implem.Pleasanter/Libraries/Settings/UserSettings.cs index ccc605011..3b19857c2 100644 --- a/Implem.Pleasanter/Libraries/Settings/UserSettings.cs +++ b/Implem.Pleasanter/Libraries/Settings/UserSettings.cs @@ -89,7 +89,7 @@ public bool AllowGroupCreation(Context context) public bool AllowApi(Context context) { if (context.HasPrivilege) return true; - return (!Parameters.User.DisableApi + return (!(Parameters.User.DisableApi || context.DisableApi) || context.User.AllowApi) && DisableApi != true; } diff --git a/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs b/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs index dc8187969..a03118b32 100644 --- a/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs +++ b/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs @@ -50,5 +50,13 @@ public ValidateInput GetRecordingData(SiteSettings ss) } return processValidateInput; } + + public bool HasNotInputValidation() + { + return ClientRegexValidation.IsNullOrEmpty() + && ServerRegexValidation.IsNullOrEmpty() + && Min == null + && Max == null; + } } } \ No newline at end of file diff --git a/Implem.Pleasanter/Libraries/Settings/View.cs b/Implem.Pleasanter/Libraries/Settings/View.cs index db1437656..7cafda68e 100644 --- a/Implem.Pleasanter/Libraries/Settings/View.cs +++ b/Implem.Pleasanter/Libraries/Settings/View.cs @@ -1519,6 +1519,14 @@ public SqlWhereCollection Where( bool requestSearchCondition = true) { if (where == null) where = new SqlWhereCollection(); + var process = ss.GetProcess( + context: context, + id: context.Forms.Int("BulkProcessingItems")); + SetBulkProcessingFilter( + context: context, + ss: ss, + process: process, + where: where); SetGeneralsWhere( context: context, ss: ss, @@ -1536,9 +1544,9 @@ public SqlWhereCollection Where( context: context, ss: ss, where: where, - permissionType: GetPermissionType( - context: context, - ss: ss)); + permissionType: process == null + ? Permissions.Types.Read + : Permissions.Types.Read | Permissions.Types.Update); if (requestSearchCondition && RequestSearchCondition( context: context, @@ -1549,15 +1557,53 @@ public SqlWhereCollection Where( return where; } - private Permissions.Types GetPermissionType(Context context, SiteSettings ss) + private void SetBulkProcessingFilter( + Context context, + SiteSettings ss, + Process process, + SqlWhereCollection where) { - var process = ss.GetProcess( - context: context, - id: context.Forms.Int("BulkProcessingItems")); - var permissionType = process == null - ? Permissions.Types.Read - : Permissions.Types.Read | Permissions.Types.Update; - return permissionType; + if (process != null) + { + process.ValidateInputs? + .Where(validateInput => validateInput.Required == true) + .ForEach(validateInput => + { + var column = ss.GetColumn( + context: context, + columnName: validateInput.ColumnName); + if (column != null) + { + switch (column.TypeName.CsTypeSummary()) + { + case Types.CsBool: + where.Bool(column, true); + break; + case Types.CsNumeric: + if (column.Nullable == true) + { + where.AddRange(CsNumericColumnsWhereNull( + column: column, + param: "\t".ToSingleList(), + negative: true)); + } + break; + case Types.CsDateTime: + where.Add(CsDateTimeColumnsWhereNull( + column: column, + param: "\t".ToSingleList(), + negative: true)); + break; + case Types.CsString: + where.Add(CsStringColumnsWhereNull( + context: context, + column: column, + negative: true)); + break; + } + } + }); + } } private void SetGeneralsWhere( @@ -2131,11 +2177,10 @@ private void CsNumericColumns( column: column, param: o, negative: negative))); - collection.AddRange(param - .Where(o => o == "\t") - .SelectMany(o => CsNumericColumnsWhereNull( - column: column, - negative: negative))); + collection.AddRange(CsNumericColumnsWhereNull( + column: column, + param: param, + negative: negative)); var valueWhere = CsNumericColumnsWhere( column: column, param: param @@ -2151,12 +2196,17 @@ private void CsNumericColumns( { if (negative) { + var param = value.Deserialize>(); where.Or(or: new SqlWhereCollection() .Add(and: collection) .Add( tableName: column.TableName(), columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: " is null")); + _operator: " is null", + _using: (column.Nullable == true && !param.Any(o => o == "\t")) + || (column.Nullable != true && !param.Any(o => ContainsZero( + from: o.Split_1st(), + to: o.Split_2nd()))))); } else { @@ -2196,35 +2246,41 @@ private SqlWhere CsNumericColumnsWhere( .Params(numList.Join())); } - private IEnumerable CsNumericColumnsWhereNull( + private SqlWhereCollection CsNumericColumnsWhereNull( Column column, + List param, bool negative = false) { - yield return new SqlWhere( - tableName: column.TableName(), + var where = new SqlWhereCollection(); + if (param.Any(o => o == "\t")) + { + where.Add(new SqlWhere( + tableName: column.TableName(), columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), _operator: negative ? " is not null" - : " is null"); - if (column.Nullable != true) - { - yield return new SqlWhere( - tableName: column.TableName(), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: negative - ? "!=0" - : "=0"); - if (column.Type == Column.Types.User && SiteInfo.AnonymousId != 0) + : " is null")); + if (column.Nullable != true) { - yield return new SqlWhere( - tableName: column.TableName(), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: (negative - ? "!=" - : "=") - + SiteInfo.AnonymousId); + where.Add(new SqlWhere( + tableName: column.TableName(), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: negative + ? "!=0" + : "=0")); + if (column.Type == Column.Types.User && SiteInfo.AnonymousId != 0) + { + where.Add(new SqlWhere( + tableName: column.TableName(), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: (negative + ? "!=" + : "=") + + SiteInfo.AnonymousId)); + } } } + return where; } private IEnumerable CsNumericRangeColumns( @@ -2248,20 +2304,27 @@ private IEnumerable CsNumericRangeColumns( : to == string.Empty ? $">={from.ToDecimal()}" : " between {0} and {1}".Params(from.ToDecimal(), to.ToDecimal())); - if (column.Nullable != true - && (to == string.Empty && from.ToDecimal() <= 0) - || (from == string.Empty && to.ToDecimal() >= 0) - || (from != string.Empty && to != string.Empty && from.ToDecimal() <= 0 && to.ToDecimal() >= 0)) + if (column.Nullable != true && !negative) { - yield return new SqlWhere( - tableName: column.TableName(), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: negative - ? " is not null" - : " is null"); + if (ContainsZero( + from: from, + to: to)) + { + yield return new SqlWhere( + tableName: column.TableName(), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: " is null"); + } } } + private bool ContainsZero(string from, string to) + { + return (to == string.Empty && from.ToDecimal() <= 0) + || (from == string.Empty && to.ToDecimal() >= 0) + || (from != string.Empty && to != string.Empty && from.ToDecimal() <= 0 && to.ToDecimal() >= 0); + } + private void CsDateTimeColumns( Context context, Column column, @@ -2281,7 +2344,6 @@ private void CsDateTimeColumns( param: param, negative: negative), CsDateTimeColumnsWhereNull( - context: context, column: column, param: param, negative: negative))); @@ -2295,7 +2357,6 @@ private void CsDateTimeColumns( param: param, negative: negative), CsDateTimeColumnsWhereNull( - context: context, column: column, param: param, negative: negative))); @@ -2465,27 +2526,17 @@ private static string ConvertDateTimeParam( } private SqlWhere CsDateTimeColumnsWhereNull( - Context context, Column column, List param, bool negative) { return param.Any(o => o == "\t") - ? new SqlWhere(or: new SqlWhereCollection( - new SqlWhere( - tableName: column.TableName(), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: negative - ? " is not null" - : " is null"), - new SqlWhere( - tableName: column.TableName(), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: " not between '{0}' and '{1}'".Params( - Parameters.General.MinTime.ToUniversal(context: context) - .ToString("yyyy/M/d H:m:s"), - Parameters.General.MaxTime.ToUniversal(context: context) - .ToString("yyyy/M/d H:m:s"))))) + ? new SqlWhere( + tableName: column.TableName(), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: negative + ? " is not null" + : " is null") : null; } @@ -2804,26 +2855,40 @@ private SqlWhere CsStringColumnsWhereNull( Column column, bool negative = false) { - return new SqlWhere(or: new SqlWhereCollection( - new SqlWhere( - tableName: column.TableItemTitleCases(context: context), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: negative - ? " is not null" - : " is null"), - new SqlWhere( - tableName: column.TableItemTitleCases(context: context), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: negative - ? "!=''" - : "=''"), - new SqlWhere( - tableName: column.TableItemTitleCases(context: context), - columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), - _operator: negative - ? "!='[]'" - : "='[]'", - _using: column.MultipleSelections == true))); + if (negative) + { + return new SqlWhere(and: new SqlWhereCollection( + new SqlWhere( + tableName: column.TableItemTitleCases(context: context), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: " is not null"), + new SqlWhere( + tableName: column.TableItemTitleCases(context: context), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: "!=''"), + new SqlWhere( + tableName: column.TableItemTitleCases(context: context), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: "!='[]'", + _using: column.MultipleSelections == true))); + } + else + { + return new SqlWhere(or: new SqlWhereCollection( + new SqlWhere( + tableName: column.TableItemTitleCases(context: context), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: " is null"), + new SqlWhere( + tableName: column.TableItemTitleCases(context: context), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: "=''"), + new SqlWhere( + tableName: column.TableItemTitleCases(context: context), + columnBrackets: ("\"" + column.Name + "\"").ToSingleArray(), + _operator: "='[]'", + _using: column.MultipleSelections == true))); + } } private void CreateCsStringSqlWhereLike( diff --git a/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs b/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs index b2dc784c3..60c3f4bae 100644 --- a/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs +++ b/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs @@ -3,6 +3,7 @@ using Implem.Libraries.Utilities; using Implem.Pleasanter.Interfaces; using Implem.Pleasanter.Libraries.DataSources; +using Implem.Pleasanter.Libraries.DataTypes; using Implem.Pleasanter.Libraries.Html; using Implem.Pleasanter.Libraries.HtmlParts; using Implem.Pleasanter.Libraries.Requests; @@ -507,7 +508,13 @@ private static void ImportIssues(Context context, Dictionary idHash, .Title(model.Title?.ToString() ?? string.Empty) .Body(model.Body, _using: model.Body != null) .StartTime(model.StartTime, _using: model.StartTime != null) - .CompletionTime(value: model.CompletionTime?.Value, _using: model.CompletionTime != null) + .CompletionTime(value: model.CompletionTime?.Value ?? new CompletionTime( + context: context, + ss: ss, + value: ss.GetColumn( + context: context, + columnName: "CompletionTime").DefaultTime(context: context), + status: model.Status).Value) .WorkValue(value: model.WorkValue?.Value, _using: model.WorkValue != null) .ProgressRate(value: model.ProgressRate?.Value, _using: model.ProgressRate != null) .Status(model.Status?.Value, _using: model.Status != null) diff --git a/Implem.Pleasanter/Models/Binaries/BinaryUtilities.cs b/Implem.Pleasanter/Models/Binaries/BinaryUtilities.cs index f24fab0a7..a1f06b382 100644 --- a/Implem.Pleasanter/Models/Binaries/BinaryUtilities.cs +++ b/Implem.Pleasanter/Models/Binaries/BinaryUtilities.cs @@ -398,8 +398,19 @@ public static string DeleteTenantImage(Context context, TenantModel tenantModel) /// /// Fixed: /// - public static string UploadImage(Context context, long id) + public static string UploadImage( + Context context, + long id) { + var columnName = context.Forms.Data("ControlId"); + if (columnName.Contains("_")) + { + columnName = columnName.Substring(columnName.IndexOf("_") + 1); + } + if (columnName.StartsWith("Comment")) + { + columnName = "Comments"; + } var invalid = BinaryValidators.OnUploadingImage(context: context); switch (invalid) { @@ -411,16 +422,62 @@ public static string UploadImage(Context context, long id) default: return invalid.MessageJson(context: context); } var file = context.PostedFiles.FirstOrDefault(); - var bin = file.Byte(); - var columnName = context.Forms.Data("ControlId"); - if (columnName.Contains("_")) - { - columnName = columnName.Substring(columnName.IndexOf("_") + 1); - } - if (columnName.StartsWith("Comment")) + UploadImage( + context: context, + id: id, + columnName: columnName, + file: file); + return new ResponseCollection(context: context) + .InsertText( + "#" + context.Forms.ControlId(), + "![image]({0})".Params(Locations.ShowFile( + context: context, + guid: file.Guid))) + .ToJson(); + } + + /// + /// Fixed: + /// + public static Error.Types UploadImage( + Context context, + SiteSettings ss, + long id, + Dictionary postedFileHash) + { + var invalid = Error.Types.None; + foreach (var file in postedFileHash) { - columnName = "Comments"; + invalid = BinaryValidators.OnUploadingImage( + context: context, + ss: ss, + columnName: file.Key); + switch (invalid) + { + case Error.Types.None: + invalid = UploadImage( + context: context, + id: id, + columnName: file.Key, + file: file.Value); + break; + default: + break; + } } + return invalid; + } + + /// + /// Fixed: + /// + public static Error.Types UploadImage( + Context context, + long id, + string columnName, + PostedFile file) + { + var bin = file.Byte(); var ss = new ItemModel( context: context, referenceId: id) @@ -472,13 +529,7 @@ public static string UploadImage(Context context, long id) .Extension(file.Extension) .Size(file.Size) .ContentType(file.ContentType))); - return new ResponseCollection(context: context) - .InsertText( - "#" + context.Forms.ControlId(), - "![image]({0})".Params(Locations.ShowFile( - context: context, - guid: file.Guid))) - .ToJson(); + return Error.Types.None; } /// diff --git a/Implem.Pleasanter/Models/Binaries/BinaryValidators.cs b/Implem.Pleasanter/Models/Binaries/BinaryValidators.cs index 8895e4d67..ac29e1a7d 100644 --- a/Implem.Pleasanter/Models/Binaries/BinaryValidators.cs +++ b/Implem.Pleasanter/Models/Binaries/BinaryValidators.cs @@ -109,7 +109,10 @@ public static Error.Types OnDeletingTenantImage(Context context, SiteSettings ss /// /// Fixed: /// - public static Error.Types OnUploadingImage(Context context) + public static Error.Types OnUploadingImage( + Context context, + SiteSettings ss = null, + string columnName = null) { if (!context.ContractSettings.Attachments()) { @@ -123,6 +126,12 @@ public static Error.Types OnUploadingImage(Context context) { return Error.Types.OverTenantStorageSize; } + if (ss?.GetColumn( + context: context, + columnName: columnName)?.AllowImage == false) + { + return Error.Types.BadRequest; + } return Error.Types.None; } diff --git a/Implem.Pleasanter/Models/Depts/DeptUtilities.cs b/Implem.Pleasanter/Models/Depts/DeptUtilities.cs index 7760c343e..f32353007 100644 --- a/Implem.Pleasanter/Models/Depts/DeptUtilities.cs +++ b/Implem.Pleasanter/Models/Depts/DeptUtilities.cs @@ -1509,7 +1509,7 @@ public static string Create(Context context, SiteSettings ss) context: context, ss: ss, deptModel: deptModel, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: deptModel.DeptId) @@ -1680,7 +1680,9 @@ private static Message UpdatedMessage( DeptModel deptModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Models/Groups/GroupUtilities.cs b/Implem.Pleasanter/Models/Groups/GroupUtilities.cs index bc5677c27..38579fc47 100644 --- a/Implem.Pleasanter/Models/Groups/GroupUtilities.cs +++ b/Implem.Pleasanter/Models/Groups/GroupUtilities.cs @@ -1501,7 +1501,7 @@ public static string Create(Context context, SiteSettings ss) context: context, ss: ss, groupModel: groupModel, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: groupModel.GroupId) @@ -1672,7 +1672,9 @@ private static Message UpdatedMessage( GroupModel groupModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Models/Issues/IssueModel.cs b/Implem.Pleasanter/Models/Issues/IssueModel.cs index 9d1cc7a2a..243179b7d 100644 --- a/Implem.Pleasanter/Models/Issues/IssueModel.cs +++ b/Implem.Pleasanter/Models/Issues/IssueModel.cs @@ -1635,25 +1635,27 @@ public ErrorData Create( ss: ss, notice: notice), type: noticeType); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } if (get) Get(context: context, ss: ss); if (ss.PermissionForCreating != null) @@ -1890,25 +1892,27 @@ public ErrorData Update( ss: ss, notice: notice)), type: "Updated"); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } if (get) { @@ -2097,6 +2101,7 @@ public void UpdateRelatedRecords( ItemUtilities.UpdateSourceTitles( context: context, ss: ss, + siteIdList: new List() { ss.SiteId }, idList: IssueId.ToSingleList()); } } @@ -3033,11 +3038,114 @@ public void SetByApi(Context context, SiteSettings ss) } SetAttachments(columnName: columnName, value: newAttachments); }); + data.ImageHash?.ForEach(o => + { + var bytes = Convert.FromBase64String(o.Value.Base64); + var stream = new System.IO.MemoryStream(bytes); + var file = new Microsoft.AspNetCore.Http.FormFile(stream, 0, bytes.Length, null, $"image{o.Value.Extension}"); + if (ss.ColumnHash.Get(o.Key).AllowImage == true) + { + SetPostedFiles( + file: file, + columnName: o.Key, + image: o.Value); + SetImageValue( + context: context, + ss: ss, + columnName: o.Key, + imageApiModel: o.Value); + } + }); RecordPermissions = data.RecordPermissions; SetByFormula(context: context, ss: ss); SetChoiceHash(context: context, ss: ss); } + public void SetPostedFiles( + Microsoft.AspNetCore.Http.IFormFile file, + string columnName, + Shared._ImageApiModel image) + { + PostedImageHash.Add( + columnName, + new PostedFile() + { + Guid = new HttpPostedFile(file).WriteToTemp(), + FileName = file.FileName.Split(System.IO.Path.DirectorySeparatorChar).Last(), + Extension = image.Extension, + Size = file.Length, + ContentType = MimeKit.MimeTypes.GetMimeType(image.Extension), + ContentRange = file.Length > 0 + ? new System.Net.Http.Headers.ContentRangeHeaderValue( + 0, + file.Length - 1, + file.Length) + : new System.Net.Http.Headers.ContentRangeHeaderValue(0, 0, 0), + InputStream = file.OpenReadStream() + }); + } + + public void SetImageValue( + Context context, + SiteSettings ss, + string columnName, + Shared._ImageApiModel imageApiModel) + { + var imageText = $"![{imageApiModel.Alt}](/binaries/{PostedImageHash.Get(columnName).Guid}/show)"; + switch (columnName) + { + case "Body": + Body = InsertImageText( + body: Body, + imageText: imageText, + imageApiModel: imageApiModel); + break; + case "Comments": + var comment = Comments.GetCreated( + context: context, + ss: ss); + comment.Body = InsertImageText( + body: comment.Body, + imageText: imageText, + imageApiModel: imageApiModel); + break; + default: + if (Def.ExtendedColumnTypes.Get(columnName) == "Description") + { + if (!DescriptionHash.ContainsKey(columnName)) + { + DescriptionHash.Add(columnName, string.Empty); + } + DescriptionHash[columnName] = InsertImageText( + body: DescriptionHash.Get(columnName), + imageText: imageText, + imageApiModel: imageApiModel); + } + break; + } + } + + public string InsertImageText( + string body, + string imageText, + Shared._ImageApiModel imageApiModel) + { + if (imageApiModel.HeadNewLine == true) + { + imageText = $"\n{imageText}"; + } + if (imageApiModel.EndNewLine == true) + { + imageText = $"{imageText}\n"; + } + var insertedBody = imageApiModel.Position.ToInt() == -1 + ? body + imageText + : imageApiModel.Position.ToInt() < body.Length + ? body.Insert(imageApiModel.Position.ToInt(), imageText) + : body + imageText; + return insertedBody; + } + public void SetByProcess( Context context, SiteSettings ss, diff --git a/Implem.Pleasanter/Models/Issues/IssueUtilities.cs b/Implem.Pleasanter/Models/Issues/IssueUtilities.cs index 8fc47b86f..119332452 100644 --- a/Implem.Pleasanter/Models/Issues/IssueUtilities.cs +++ b/Implem.Pleasanter/Models/Issues/IssueUtilities.cs @@ -3093,7 +3093,7 @@ public static string Create(Context context, SiteSettings ss) context: context, ss: ss, issueModel: issueModel, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: issueModel.IssueId) @@ -3197,6 +3197,11 @@ public static ContentResultInheritance CreateByApi(Context context, SiteSettings context: context, ss: ss, notice: true); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: issueModel.IssueId, + postedFileHash: issueModel.PostedImageHash); switch (errorData.Type) { case Error.Types.None: @@ -3508,7 +3513,9 @@ private static Message UpdatedMessage( IssueModel issueModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( @@ -4064,7 +4071,7 @@ public static string BulkProcess(Context context, SiteSettings ss) var process = ss.GetProcess( context: context, id: processId); - if (process == null) + if (process == null || !process.GetAllowBulkProcessing()) { return Messages.NotFound(context: context).ToJson(); } @@ -4232,6 +4239,11 @@ public static ContentResultInheritance UpdateByApi( ss: ss, notice: true, previousTitle: previousTitle); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: issueModel.IssueId, + postedFileHash: issueModel.PostedImageHash); switch (errorData.Type) { case Error.Types.None: @@ -4392,6 +4404,11 @@ public static ContentResultInheritance UpsertByApi( ss: ss, notice: true, previousTitle: previousTitle); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: issueModel.IssueId, + postedFileHash: issueModel.PostedImageHash); switch (errorData.Type) { case Error.Types.None: diff --git a/Implem.Pleasanter/Models/Items/ItemUtilities.cs b/Implem.Pleasanter/Models/Items/ItemUtilities.cs index 9af1dde9f..a12159550 100644 --- a/Implem.Pleasanter/Models/Items/ItemUtilities.cs +++ b/Implem.Pleasanter/Models/Items/ItemUtilities.cs @@ -74,45 +74,55 @@ public static SqlJoinCollection ItemJoin( } } - public static void UpdateSourceTitles(Context context, SiteSettings ss, IList idList) + public static void UpdateSourceTitles( + Context context, + SiteSettings ss, + IList siteIdList, + IList idList) { - ss.Sources - .ForEach(source => + ss.Sources.ForEach(source => + { + var currentSs = source.Value; + var columns = currentSs?.Links + ?.Where(o => o.SiteId > 0) + .Where(o => o.SiteId == ss.SiteId) + .Select(o => o.ColumnName) + .ToList(); + if (currentSs?.TitleColumns?.Any(o => columns?.Contains(o) == true) == true) { - var currentSs = source.Value; - var columns = currentSs?.Links - ?.Where(o => o.SiteId > 0) - .Where(o => o.SiteId == ss.SiteId) - .Select(o => o.ColumnName) - .ToList(); - if (currentSs?.TitleColumns?.Any(o => columns?.Contains(o) == true) == true) + currentSs.SetLinkedSiteSettings(context: context); + if (!siteIdList.Contains(currentSs.SiteId)) { - var nextIdList = - Repository.ExecuteTable( - context: context, - statements: Rds.SelectLinks( - column: Rds.LinksColumn() - .SourceId(), - join: Rds.LinksJoinDefault(), - where: Rds.LinksWhere() - .SiteId(currentSs.SiteId) - .DestinationId_In( - value: idList, - _using: idList.Count <= 100))) - .AsEnumerable() - .Select(dataRow => dataRow.Long("SourceId")) - .ToList(); - currentSs.SetLinkedSiteSettings(context: context); + siteIdList.Add(currentSs.SiteId); + var nextIdList = Repository.ExecuteTable( + context: context, + statements: Rds.SelectLinks( + column: Rds.LinksColumn() + .SourceId(), + join: Rds.LinksJoinDefault(), + where: Rds.LinksWhere() + .SiteId(currentSs.SiteId) + .DestinationId_In( + value: idList, + _using: idList.Count <= 100))) + .AsEnumerable() + .Select(dataRow => dataRow.Long("SourceId")) + .ToList(); UpdateTitles( context: context, ss: currentSs, + siteIdList: siteIdList, idList: nextIdList); } - }); + } + }); } public static void UpdateTitles( - Context context, SiteSettings ss, IList idList = null) + Context context, + SiteSettings ss, + IList siteIdList, + IList idList = null) { switch (ss?.ReferenceType) { @@ -120,18 +130,21 @@ public static void UpdateTitles( UpdateIssueTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: idList); break; case "Results": UpdateResultTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: idList); break; case "Wikis": UpdateWikiTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: idList); break; default: @@ -140,7 +153,10 @@ public static void UpdateTitles( } private static void UpdateIssueTitles( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList siteIdList, + IList idList) { var issues = GetIssues( context: context, @@ -179,12 +195,15 @@ private static void UpdateIssueTitles( UpdateSourceTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: issues.Select(o => o.IssueId).ToList()); } } private static List GetIssues( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList idList) { var column = Rds.IssuesColumn() .IssueId() @@ -207,7 +226,10 @@ private static List GetIssues( } private static void UpdateResultTitles( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList siteIdList, + IList idList) { var results = GetResults( context: context, @@ -246,12 +268,15 @@ private static void UpdateResultTitles( UpdateSourceTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: results.Select(o => o.ResultId).ToList()); } } private static List GetResults( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList idList) { var column = Rds.ResultsColumn() .ResultId() @@ -274,7 +299,10 @@ private static List GetResults( } private static void UpdateWikiTitles( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList siteIdList, + IList idList) { var wikis = GetWikis( context: context, @@ -313,12 +341,15 @@ private static void UpdateWikiTitles( UpdateSourceTitles( context: context, ss: ss, + siteIdList: siteIdList, idList: wikis.Select(o => o.WikiId).ToList()); } } private static List GetWikis( - Context context, SiteSettings ss, IList idList) + Context context, + SiteSettings ss, + IList idList) { var column = Rds.WikisColumn() .WikiId() diff --git a/Implem.Pleasanter/Models/Registrations/RegistrationUtilities.cs b/Implem.Pleasanter/Models/Registrations/RegistrationUtilities.cs index 4f06d73c6..b627d9da1 100644 --- a/Implem.Pleasanter/Models/Registrations/RegistrationUtilities.cs +++ b/Implem.Pleasanter/Models/Registrations/RegistrationUtilities.cs @@ -1925,7 +1925,9 @@ private static Message UpdatedMessage( RegistrationModel registrationModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Models/Results/ResultModel.cs b/Implem.Pleasanter/Models/Results/ResultModel.cs index 8f441187c..06019a123 100644 --- a/Implem.Pleasanter/Models/Results/ResultModel.cs +++ b/Implem.Pleasanter/Models/Results/ResultModel.cs @@ -1406,25 +1406,27 @@ public ErrorData Create( ss: ss, notice: notice), type: noticeType); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } if (get) Get(context: context, ss: ss); if (ss.PermissionForCreating != null) @@ -1661,25 +1663,27 @@ public ErrorData Update( ss: ss, notice: notice)), type: "Updated"); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } if (get) { @@ -1868,6 +1872,7 @@ public void UpdateRelatedRecords( ItemUtilities.UpdateSourceTitles( context: context, ss: ss, + siteIdList: new List() { ss.SiteId }, idList: ResultId.ToSingleList()); } } @@ -2731,11 +2736,114 @@ public void SetByApi(Context context, SiteSettings ss) } SetAttachments(columnName: columnName, value: newAttachments); }); + data.ImageHash?.ForEach(o => + { + var bytes = Convert.FromBase64String(o.Value.Base64); + var stream = new System.IO.MemoryStream(bytes); + var file = new Microsoft.AspNetCore.Http.FormFile(stream, 0, bytes.Length, null, $"image{o.Value.Extension}"); + if (ss.ColumnHash.Get(o.Key).AllowImage == true) + { + SetPostedFiles( + file: file, + columnName: o.Key, + image: o.Value); + SetImageValue( + context: context, + ss: ss, + columnName: o.Key, + imageApiModel: o.Value); + } + }); RecordPermissions = data.RecordPermissions; SetByFormula(context: context, ss: ss); SetChoiceHash(context: context, ss: ss); } + public void SetPostedFiles( + Microsoft.AspNetCore.Http.IFormFile file, + string columnName, + Shared._ImageApiModel image) + { + PostedImageHash.Add( + columnName, + new PostedFile() + { + Guid = new HttpPostedFile(file).WriteToTemp(), + FileName = file.FileName.Split(System.IO.Path.DirectorySeparatorChar).Last(), + Extension = image.Extension, + Size = file.Length, + ContentType = MimeKit.MimeTypes.GetMimeType(image.Extension), + ContentRange = file.Length > 0 + ? new System.Net.Http.Headers.ContentRangeHeaderValue( + 0, + file.Length - 1, + file.Length) + : new System.Net.Http.Headers.ContentRangeHeaderValue(0, 0, 0), + InputStream = file.OpenReadStream() + }); + } + + public void SetImageValue( + Context context, + SiteSettings ss, + string columnName, + Shared._ImageApiModel imageApiModel) + { + var imageText = $"![{imageApiModel.Alt}](/binaries/{PostedImageHash.Get(columnName).Guid}/show)"; + switch (columnName) + { + case "Body": + Body = InsertImageText( + body: Body, + imageText: imageText, + imageApiModel: imageApiModel); + break; + case "Comments": + var comment = Comments.GetCreated( + context: context, + ss: ss); + comment.Body = InsertImageText( + body: comment.Body, + imageText: imageText, + imageApiModel: imageApiModel); + break; + default: + if (Def.ExtendedColumnTypes.Get(columnName) == "Description") + { + if (!DescriptionHash.ContainsKey(columnName)) + { + DescriptionHash.Add(columnName, string.Empty); + } + DescriptionHash[columnName] = InsertImageText( + body: DescriptionHash.Get(columnName), + imageText: imageText, + imageApiModel: imageApiModel); + } + break; + } + } + + public string InsertImageText( + string body, + string imageText, + Shared._ImageApiModel imageApiModel) + { + if (imageApiModel.HeadNewLine == true) + { + imageText = $"\n{imageText}"; + } + if (imageApiModel.EndNewLine == true) + { + imageText = $"{imageText}\n"; + } + var insertedBody = imageApiModel.Position.ToInt() == -1 + ? body + imageText + : imageApiModel.Position.ToInt() < body.Length + ? body.Insert(imageApiModel.Position.ToInt(), imageText) + : body + imageText; + return insertedBody; + } + public void SetByProcess( Context context, SiteSettings ss, diff --git a/Implem.Pleasanter/Models/Results/ResultUtilities.cs b/Implem.Pleasanter/Models/Results/ResultUtilities.cs index b8fbaa21a..aae8486eb 100644 --- a/Implem.Pleasanter/Models/Results/ResultUtilities.cs +++ b/Implem.Pleasanter/Models/Results/ResultUtilities.cs @@ -2912,7 +2912,7 @@ public static string Create(Context context, SiteSettings ss) context: context, ss: ss, resultModel: resultModel, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: resultModel.ResultId) @@ -3016,6 +3016,11 @@ public static ContentResultInheritance CreateByApi(Context context, SiteSettings context: context, ss: ss, notice: true); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: resultModel.ResultId, + postedFileHash: resultModel.PostedImageHash); switch (errorData.Type) { case Error.Types.None: @@ -3320,7 +3325,9 @@ private static Message UpdatedMessage( ResultModel resultModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( @@ -3876,7 +3883,7 @@ public static string BulkProcess(Context context, SiteSettings ss) var process = ss.GetProcess( context: context, id: processId); - if (process == null) + if (process == null || !process.GetAllowBulkProcessing()) { return Messages.NotFound(context: context).ToJson(); } @@ -4044,6 +4051,11 @@ public static ContentResultInheritance UpdateByApi( ss: ss, notice: true, previousTitle: previousTitle); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: resultModel.ResultId, + postedFileHash: resultModel.PostedImageHash); switch (errorData.Type) { case Error.Types.None: @@ -4204,6 +4216,11 @@ public static ContentResultInheritance UpsertByApi( ss: ss, notice: true, previousTitle: previousTitle); + BinaryUtilities.UploadImage( + context: context, + ss: ss, + id: resultModel.ResultId, + postedFileHash: resultModel.PostedImageHash); switch (errorData.Type) { case Error.Types.None: diff --git a/Implem.Pleasanter/Models/Shared/_BaseApiModel.cs b/Implem.Pleasanter/Models/Shared/_BaseApiModel.cs index 08cf99721..40bc97be3 100644 --- a/Implem.Pleasanter/Models/Shared/_BaseApiModel.cs +++ b/Implem.Pleasanter/Models/Shared/_BaseApiModel.cs @@ -804,6 +804,7 @@ public class _BaseApiModel public Attachment[] PostedFilesX { get; set; } public Attachment[] PostedFilesY { get; set; } public Attachment[] PostedFilesZ { get; set; } + public Dictionary ImageHash { get; set; } public _BaseApiModel() diff --git a/Implem.Pleasanter/Models/Shared/_BaseModel.cs b/Implem.Pleasanter/Models/Shared/_BaseModel.cs index b9d6c6baa..d0392fe0c 100644 --- a/Implem.Pleasanter/Models/Shared/_BaseModel.cs +++ b/Implem.Pleasanter/Models/Shared/_BaseModel.cs @@ -90,6 +90,7 @@ public bool Updator_Updated(Context context, Column column = null) public Dictionary SavedCheckHash = new Dictionary(); public Dictionary AttachmentsHash = new Dictionary(); public Dictionary SavedAttachmentsHash = new Dictionary(); + public Dictionary PostedImageHash = new Dictionary(); public bool ReadOnly; public List MineCache; [NonSerialized] diff --git a/Implem.Pleasanter/Models/Shared/_ImageApiModel.cs b/Implem.Pleasanter/Models/Shared/_ImageApiModel.cs new file mode 100644 index 000000000..e242c12d6 --- /dev/null +++ b/Implem.Pleasanter/Models/Shared/_ImageApiModel.cs @@ -0,0 +1,21 @@ +namespace Implem.Pleasanter.Models.Shared +{ + public class _ImageApiModel + { + public bool? HeadNewLine { get; set; } + public bool? EndNewLine { get; set; } + public int? Position { get; set; } + public string Alt { get; set; } + public string Extension { get; set; } + public string Base64 { get; set; } + + public _ImageApiModel() + { + HeadNewLine = HeadNewLine ?? false; + EndNewLine = EndNewLine ?? false; + Position = Position ?? -1; + Alt = Alt ?? "image"; + Extension = Extension ?? ".png"; + } + } +} diff --git a/Implem.Pleasanter/Models/Sites/SiteUtilities.cs b/Implem.Pleasanter/Models/Sites/SiteUtilities.cs index d8302ab1d..036af005a 100644 --- a/Implem.Pleasanter/Models/Sites/SiteUtilities.cs +++ b/Implem.Pleasanter/Models/Sites/SiteUtilities.cs @@ -1237,7 +1237,9 @@ private static Message UpdatedMessage( SiteModel siteModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( @@ -10820,7 +10822,9 @@ private static HtmlBuilder ViewKambanTab( controlId: "KambanGroupByY", fieldCss: "field-auto-thin", labelText: Displays.GroupByY(context: context), - optionCollection: ss.KambanGroupByOptions(context: context), + optionCollection: ss.KambanGroupByOptions( + context: context, + addNothing: true), selectedValue: view.KambanGroupByY, insertBlank: true) .FieldDropDown( @@ -13907,7 +13911,10 @@ public static string SynchronizeTitles(Context context, SiteModel siteModel) case Error.Types.None: break; default: return invalid.MessageJson(context: context); } - ItemUtilities.UpdateTitles(context: context, ss: ss); + ItemUtilities.UpdateTitles( + context: context, + ss: ss, + siteIdList: new List { ss.SiteId }); return Messages.ResponseSynchronizationCompleted(context: context).ToJson(); } diff --git a/Implem.Pleasanter/Models/SysLogs/SysLogUtilities.cs b/Implem.Pleasanter/Models/SysLogs/SysLogUtilities.cs index 2f56c1a84..150217e98 100644 --- a/Implem.Pleasanter/Models/SysLogs/SysLogUtilities.cs +++ b/Implem.Pleasanter/Models/SysLogs/SysLogUtilities.cs @@ -1982,7 +1982,7 @@ public static string Create(Context context, SiteSettings ss) context: context, ss: ss, sysLogModel: sysLogModel, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: sysLogModel.SysLogId) @@ -2153,7 +2153,9 @@ private static Message UpdatedMessage( SysLogModel sysLogModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Models/Tenants/TenantApiModel.cs b/Implem.Pleasanter/Models/Tenants/TenantApiModel.cs index e068f7b5f..96612b416 100644 --- a/Implem.Pleasanter/Models/Tenants/TenantApiModel.cs +++ b/Implem.Pleasanter/Models/Tenants/TenantApiModel.cs @@ -14,6 +14,7 @@ public class TenantApiModel : _BaseApiModel public string ContractSettings { get; set; } public DateTime? ContractDeadline { get; set; } public bool? DisableAllUsersPermission { get; set; } + public bool? DisableApi { get; set; } public bool? DisableStartGuide { get; set; } public int? LogoType { get; set; } public string HtmlTitleTop { get; set; } @@ -43,6 +44,7 @@ public override object ObjectValue(string columnName) case "ContractSettings": return ContractSettings; case "ContractDeadline": return ContractDeadline; case "DisableAllUsersPermission": return DisableAllUsersPermission; + case "DisableApi": return DisableApi; case "DisableStartGuide": return DisableStartGuide; case "LogoType": return LogoType; case "HtmlTitleTop": return HtmlTitleTop; diff --git a/Implem.Pleasanter/Models/Tenants/TenantModel.cs b/Implem.Pleasanter/Models/Tenants/TenantModel.cs index 1b343fb72..cf559b091 100644 --- a/Implem.Pleasanter/Models/Tenants/TenantModel.cs +++ b/Implem.Pleasanter/Models/Tenants/TenantModel.cs @@ -33,6 +33,7 @@ public class TenantModel : BaseModel public ContractSettings ContractSettings = new ContractSettings(); public DateTime ContractDeadline = 0.ToDateTime(); public bool DisableAllUsersPermission = false; + public bool DisableApi = false; public bool DisableStartGuide = false; public LogoTypes LogoType = (LogoTypes)0; public string HtmlTitleTop = "[ProductName]"; @@ -47,6 +48,7 @@ public class TenantModel : BaseModel public string SavedContractSettings = string.Empty; public DateTime SavedContractDeadline = 0.ToDateTime(); public bool SavedDisableAllUsersPermission = false; + public bool SavedDisableApi = false; public bool SavedDisableStartGuide = false; public int SavedLogoType = 0; public string SavedHtmlTitleTop = "[ProductName]"; @@ -103,6 +105,14 @@ public bool DisableAllUsersPermission_Updated(Context context, Column column = n column.GetDefaultInput(context: context).ToBool() != DisableAllUsersPermission); } + public bool DisableApi_Updated(Context context, Column column = null) + { + return DisableApi != SavedDisableApi && + (column == null || + column.DefaultInput.IsNullOrEmpty() || + column.GetDefaultInput(context: context).ToBool() != DisableApi); + } + public bool DisableStartGuide_Updated(Context context, Column column = null) { return DisableStartGuide != SavedDisableStartGuide && @@ -321,6 +331,7 @@ public TenantApiModel GetByApi(Context context, SiteSettings ss) case "ContractSettings": data.ContractSettings = ContractSettings?.RecordingJson(); break; case "ContractDeadline": data.ContractDeadline = ContractDeadline.ToLocal(context: context); break; case "DisableAllUsersPermission": data.DisableAllUsersPermission = DisableAllUsersPermission; break; + case "DisableApi": data.DisableApi = DisableApi; break; case "DisableStartGuide": data.DisableStartGuide = DisableStartGuide; break; case "LogoType": data.LogoType = LogoType.ToInt(); break; case "HtmlTitleTop": data.HtmlTitleTop = HtmlTitleTop; break; @@ -384,6 +395,11 @@ public string ToDisplay(Context context, SiteSettings ss, Column column, List o.MatchConditions))); return new ResponseCollection( context: context, id: tenantModel.TenantId) @@ -1325,7 +1337,9 @@ private static Message UpdatedMessage( TenantModel tenantModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Models/Tenants/TenantValidators.cs b/Implem.Pleasanter/Models/Tenants/TenantValidators.cs index b250e59cb..06cb51d6a 100644 --- a/Implem.Pleasanter/Models/Tenants/TenantValidators.cs +++ b/Implem.Pleasanter/Models/Tenants/TenantValidators.cs @@ -153,6 +153,12 @@ public static ErrorData OnCreating( return new ErrorData(type: Error.Types.HasNotPermission); } break; + case "DisableApi": + if (tenantModel.DisableApi_Updated(context: context, column: column)) + { + return new ErrorData(type: Error.Types.HasNotPermission); + } + break; case "DisableStartGuide": if (tenantModel.DisableStartGuide_Updated(context: context, column: column)) { @@ -332,6 +338,12 @@ public static ErrorData OnUpdating( return new ErrorData(type: Error.Types.HasNotPermission); } break; + case "DisableApi": + if (tenantModel.DisableApi_Updated(context: context)) + { + return new ErrorData(type: Error.Types.HasNotPermission); + } + break; case "DisableStartGuide": if (tenantModel.DisableStartGuide_Updated(context: context)) { diff --git a/Implem.Pleasanter/Models/Users/UserUtilities.cs b/Implem.Pleasanter/Models/Users/UserUtilities.cs index f1468e5dd..a5263e951 100644 --- a/Implem.Pleasanter/Models/Users/UserUtilities.cs +++ b/Implem.Pleasanter/Models/Users/UserUtilities.cs @@ -2482,7 +2482,7 @@ public static string Create(Context context, SiteSettings ss) context: context, ss: ss, userModel: userModel, - process: processes?.FirstOrDefault())); + process: processes?.FirstOrDefault(o => o.MatchConditions))); return new ResponseCollection( context: context, id: userModel.UserId) @@ -2658,7 +2658,9 @@ private static Message UpdatedMessage( UserModel userModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Models/Wikis/WikiModel.cs b/Implem.Pleasanter/Models/Wikis/WikiModel.cs index 3ff2518a3..acfa36516 100644 --- a/Implem.Pleasanter/Models/Wikis/WikiModel.cs +++ b/Implem.Pleasanter/Models/Wikis/WikiModel.cs @@ -641,25 +641,27 @@ public ErrorData Create( ss: ss, notice: notice), type: noticeType); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } if (get) Get(context: context, ss: ss); var fullText = FullText(context, ss: ss, onCreating: true); @@ -809,25 +811,27 @@ public ErrorData Update( ss: ss, notice: notice)), type: "Updated"); - processes?.ForEach(process => - process?.Notifications?.ForEach(notification => - notification.Send( - context: context, - ss: ss, - title: ReplacedDisplayValues( - context: context, - ss: ss, - value: notification.Subject), - body: ReplacedDisplayValues( + processes? + .Where(process => process.MatchConditions) + .ForEach(process => + process?.Notifications?.ForEach(notification => + notification.Send( context: context, ss: ss, - value: notification.Body), - values: ss.IncludedColumns(notification.Address) - .ToDictionary( - column => column, - column => PropertyValue( - context: context, - column: column))))); + title: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Subject), + body: ReplacedDisplayValues( + context: context, + ss: ss, + value: notification.Body), + values: ss.IncludedColumns(notification.Address) + .ToDictionary( + column => column, + column => PropertyValue( + context: context, + column: column))))); } if (get) { @@ -975,6 +979,7 @@ public void UpdateRelatedRecords( ItemUtilities.UpdateSourceTitles( context: context, ss: ss, + siteIdList: new List() { ss.SiteId }, idList: WikiId.ToSingleList()); } } diff --git a/Implem.Pleasanter/Models/Wikis/WikiUtilities.cs b/Implem.Pleasanter/Models/Wikis/WikiUtilities.cs index 6cecdd532..21392e02c 100644 --- a/Implem.Pleasanter/Models/Wikis/WikiUtilities.cs +++ b/Implem.Pleasanter/Models/Wikis/WikiUtilities.cs @@ -1684,7 +1684,9 @@ private static Message UpdatedMessage( WikiModel wikiModel, List processes) { - var process = processes.FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty()); + var process = processes + .FirstOrDefault(o => !o.SuccessMessage.IsNullOrEmpty() + && o.MatchConditions); if (process == null) { return Messages.Updated( diff --git a/Implem.Pleasanter/Startup.cs b/Implem.Pleasanter/Startup.cs index f62953da3..ad114de78 100644 --- a/Implem.Pleasanter/Startup.cs +++ b/Implem.Pleasanter/Startup.cs @@ -152,15 +152,16 @@ public void ConfigureServices(IServiceCollection services) { options.BackgroundServiceExceptionBehavior = BackgroundServiceExceptionBehavior.Ignore; }); - if (Parameters.BackgroundService.Reminder) + if (Parameters.BackgroundService.ReminderEnabled( + deploymentEnvironment: Parameters.Service.DeploymentEnvironment)) { services.AddHostedService(); } - if (Parameters.BackgroundService.TimerEnabled()) + if (Parameters.BackgroundService.TimerEnabled( + deploymentEnvironment: Parameters.Service.DeploymentEnvironment)) { services.AddHostedService(); } - var blobContainerUri = Parameters.Security.AspNetCoreDataProtection?.BlobContainerUri; var keyIdentifier = Parameters.Security.AspNetCoreDataProtection?.KeyIdentifier; if (!blobContainerUri.IsNullOrEmpty() diff --git a/Implem.Pleasanter/wwwroot/content/styles.css b/Implem.Pleasanter/wwwroot/content/styles.css index 334ac96a0..cb48d031d 100644 --- a/Implem.Pleasanter/wwwroot/content/styles.css +++ b/Implem.Pleasanter/wwwroot/content/styles.css @@ -181,9 +181,10 @@ pre{ } #PortalLink{ - position:fixed; - top:10px; + position:relative; + top:-38px; right:40px; + float:right; } #LoginFieldSet{ @@ -255,7 +256,6 @@ pre{ #Header{ width:100%; - height:42px; float:left; padding:0px 6px; border:none; @@ -265,13 +265,13 @@ pre{ #Navigations{ height:30px; - margin:5px 0px; + margin:0px 0px 5px 0px; padding:0px 5px 0px 15px; border:none; - position:absolute; top:0px; right:5px; border-radius:20px 5px 5px 20px; + float:right; } #NavigationMenu{ @@ -1852,7 +1852,7 @@ td > .field-normal,td > .field-wide{ overflow:hidden; } -.field-label .required:after{ +label.required:after{ margin-left:3px; color:red; content:'*'; diff --git a/Implem.Pleasanter/wwwroot/content/styles.min.css b/Implem.Pleasanter/wwwroot/content/styles.min.css index 3b81fc274..231b6723a 100644 --- a/Implem.Pleasanter/wwwroot/content/styles.min.css +++ b/Implem.Pleasanter/wwwroot/content/styles.min.css @@ -1 +1 @@ -@charset "utf-8";*{box-sizing:border-box}html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-style:normal;font-weight:normal;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}input,textarea{margin:0;padding:0}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}caption,th{text-align:left}a:focus{outline:none}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.both{clear:both}img{max-width:100%;height:auto;width:auto}::-webkit-input-placeholder{color:#c0c0c0}:-moz-placeholder{color:#c0c0c0;opacity:1}::-moz-placeholder{color:#c0c0c0;opacity:1}:-ms-input-placeholder{color:#c0c0c0}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type="number"]{-moz-appearance:textfield}body{min-width:1200px;font-size:.75em;font-family:Hiragino Kaku Gothic Pro,"Meiryo UI",sans-serif;clear:both}h1{clear:both}h2{clear:both}h3{clear:both}legend{cursor:pointer}legend>*{display:block;float:left}label{position:relative;cursor:pointer;z-index:2}input{background-color:#fff;position:relative;z-index:2}select{position:relative;z-index:2}table{width:100%;border:0;border-collapse:collapse;clear:both}td{padding:3px;vertical-align:top;color:#000}td.right-align>p{float:right}pre{line-height:1.5em;font-family:Terminal;word-wrap:break-word;word-break:break-all;white-space:pre-wrap}#Logo{padding:3px 0}#CorpLogo{display:block;float:left;margin:3px 0 0 0}#ProductLogo{display:block;float:left;padding:0 0 0 5px;font-size:26px;font-weight:bold;color:#696969;text-decoration:none}#PortalLink{position:fixed;top:10px;right:40px}#LoginFieldSet{width:500px;margin:150px auto 20px auto;padding:50px;background-color:#f5f5f5;border-radius:10px}#LoginCommands{text-align:right;clear:both}#Demo{width:500px;margin:0 auto}#DemoFields{padding:20px 10px 10px 10px}#SearchPermissionElements{margin-left:15px}#Breadcrumb{float:left;margin:0 0 5px 0}#Breadcrumb .item{display:block;float:left;padding:3px 5px}#Breadcrumb .item.trashbox{display:block;float:left;color:#fff;background-color:#f00;border-radius:3px}#Breadcrumb .separator{margin:0 0 0 8px}#Guide>div{width:100%;display:block;float:left;margin:0 0 5px 0;padding:5px 10px;background:#fafad2;border:solid 1px #c0c0c0;position:relative;clear:both;border-radius:5px}#CopyToClipboards>.display-control{float:left;cursor:pointer}#Header{width:100%;height:42px;float:left;padding:0 6px;border:none;position:relative;clear:both}#Navigations{height:30px;margin:5px 0;padding:0 5px 0 15px;border:none;position:absolute;top:0;right:5px;border-radius:20px 5px 5px 20px}#NavigationMenu{float:left;margin-right:5px}#NavigationMenu>li{width:158px;height:30px;display:block;float:left;position:relative}#NavigationMenu>li>div{height:30px;text-align:center;line-height:30px;cursor:pointer}#NavigationMenu>li>div>a{height:30px;display:block;text-decoration:none}#NavigationMenu .menu{width:158px;display:none;border-top:none !important;position:absolute;top:30px;right:0;border-radius:0 0 5px 5px;z-index:3}#NavigationMenu .menu>li>a{display:block;text-decoration:none}#NavigationMenu .menu>li>a.ui-state-active{font-weight:normal;text-decoration:none}#TemplateDialog>div{padding:0 15px;overflow:hidden}#SearchField{float:left;margin:3px 0;color:#000}#Search{height:24px}#SwitchUserInfo{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;color:#fff;background-color:#00f;border-radius:7px}#SwitchUserInfo>a{width:100%;display:block;float:left;color:#fff;text-decoration:none}#ExcessLicenseWarning{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;color:#fff;background:#f00;border-radius:7px}#PublishWarning{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;background:#f00;border-radius:7px}#PublishWarning>a{width:100%;display:block;float:left;color:#fff;text-decoration:none}#LockedWarning{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;background:#f00;border-radius:7px}#LockedWarning>div{width:100%;display:block;float:left;color:#fff;text-decoration:none}#Application{width:100%;float:left;margin:10px 0 0 0;padding:0 10px 120px 10px;position:relative;clear:both}#Application>.site-image-icon{display:block;float:left;margin:0 10px 0 0}#StartGuide{width:100%;display:block;float:left;margin:0 0 10px 0;padding:50px 0 0 0;background-color:#f5f5f5;position:relative;border-radius:10px}#StartGuide>#StartGuideContents{width:900px;margin:0 auto}#StartGuide>#StartGuideContents>a{width:150px;display:block;float:left;margin:0 37px;padding:5px;text-align:center;border-radius:5px}#StartGuide>#StartGuideContents>a:hover{background-color:#fff}#StartGuide>#StartGuideContents>a>*{display:block;text-align:center;clear:both}#StartGuide>#StartGuideContents>a>img{width:50px;margin:5px 50px}#StartGuide>#DisableStartGuideField{display:block;float:left;margin:50px 0 0 20px;clear:both}#StartGuide>.ui-icon{position:absolute;top:10px;right:10px;cursor:pointer}#SiteImageIconContainer{float:left}#SiteImageIconContainer>*{margin:0 5px 0 0}#HeaderTitleContainer{float:left;margin:0 0 10px 0}#HeaderTitle{font-size:20px;font-weight:bold;color:#d2691e}#Notes>*{width:100%;float:left;margin:0 10px 5px 0}#Notes>.history{width:100%;display:block;float:left;padding:5px 10px;color:#fff;background-color:#00f;border-radius:7px}#Notes>.readonly{width:100%;display:block;float:left;padding:5px 10px;color:#fff;background-color:#ffa500;border-radius:7px}#ViewSelectorField{position:absolute;top:-10px;right:0}#ViewFilters{width:100%;float:left;margin:0 0 5px 0;padding:5px 5px 2px 5px;border:solid 1px #c0c0c0;border-radius:5px}#ViewFilters.reduced{width:auto;padding:0;border:none}#ViewFilters>.field-auto-thin{height:32px;float:left;padding:0}#ViewFilters_Reset{display:block;float:left;margin:0 20px 0 0}#ViewFilters>.display-control{float:left;margin:0 5px 0 0;padding:5px 10px 5px 0;font-weight:bold;cursor:pointer}#ViewFilters .ui-icon.ui-icon-info{transform:scale(1,-1)}#FilterButton{display:block;float:left}#Aggregations{width:100%;float:left;margin:0 0 5px 0;padding:3px 5px 5px 5px;border:solid 1px #c0c0c0;border-radius:5px}#Aggregations.reduced{width:auto;padding:0;border:none}#Aggregations .label{height:26px;display:block;float:left;margin:2px 5px 0 0;padding:5px 10px;background:#dcdcdc;border-radius:5px}#Aggregations .label.overdue{font-weight:bold;color:#fff;background-color:#f00;cursor:pointer}#Aggregations .data{height:26px;display:block;float:left;margin:2px 5px 0 0;padding:5px}#Aggregations .data.overdue{color:#f00;cursor:pointer}#Aggregations em{display:block;float:left;margin-right:5px;font-weight:bold}#Aggregations>.display-control{float:left;margin:0 5px 0 0;padding:5px 10px 5px 0;font-weight:bold;cursor:pointer}#SitePackagesSelectable span.include-data{margin:0 0 0 10px;color:#f00}#CalendarDate{margin-right:10px}#CalendarBody table{table-layout:fixed}#CalendarBody thead th{padding:5px;text-align:center;border:solid 1px #c0c0c0}th.calendar-header{text-align:center;background-color:#fff}#CalendarBody .saturday{background-color:#add8e6}#CalendarBody .sunday{background-color:#ffc0cb}#CalendarBody td{padding:0;border:solid 1px #c0c0c0}#CalendarBody td>div{min-height:50px;padding:5px}#CalendarBody td.hover{background-color:#f5f5f5}#CalendarBody .other-month{background-color:#dcdcdc}#CalendarBody .today{border:solid 2px #00f;z-index:20}#CalendarBody .item{height:25px;margin:5px 0 0 0;background-color:#fafad2;border:solid 1px #c0c0c0;border-radius:3px}#CalendarBody .item.hover{background-color:#fff;border:solid 1px #ffa500}#CalendarBody .item.changed{font-weight:bold;background-color:#ff0;border:solid 1px #ffa500}#CalendarBody .item .connection{width:14px;height:25px;background-color:#fafad2;border-top:solid 1px #c0c0c0;border-bottom:solid 1px #c0c0c0;position:relative;top:-1px;left:-14px}#CalendarBody .item .connection.hover{background-color:#fff;border-top:solid 1px #ffa500;border-bottom:solid 1px #ffa500}#CalendarBody .item .connection.changed{font-weight:bold;background-color:#ff0;border-top:solid 1px #ffa500;border-bottom:solid 1px #ffa500}#CalendarBody .item .title{padding:5px 0;position:absolute;overflow:hidden;white-space:nowrap;z-index:30}#CalendarBody .item .title.sub{display:none}#CalendarBody .dragging{height:25px;padding:5px;background-color:#fafad2;border-radius:3px;z-index:50}#CalendarBody .dummy{height:25px;margin:5px 0 0 0}#Crosstab .crosstab-row{border-bottom:dotted 1px #c0c0c0}#Crosstab .saturday{background-color:#eee}#Crosstab .sunday{background-color:#fee}#CrosstabMonth{margin-right:10px}#Gantt{width:100%;background-color:#f5f5f5;border-radius:20px}#Gantt .saturday{fill:#eee}#Gantt .sunday{fill:#fee}#Gantt .date{stroke:white}#Gantt .now{stroke:red}#Gantt .planned rect{cursor:pointer;fill:gainsboro}#Gantt .planned rect.summary{cursor:auto}#Gantt .earned rect{cursor:pointer;fill:darkseagreen}#Gantt .earned rect.summary{cursor:auto}#Gantt rect.delay{fill:#ffccd5}#Gantt rect.completed{fill:lightsteelblue}#Gantt .title text{cursor:pointer}#Gantt .title text.delay{fill:red}#Gantt .title text.summary{font-size:1.2em;font-weight:bold;cursor:auto}#GanttStartDate{margin-right:10px}#GanttAxis{width:calc(100% + 20px);height:50px;margin-left:-10px;margin-top:-25px;background-color:rgba(255,255,255,.5);position:sticky;left:0;bottom:75px}#GanttAxis .saturday{fill:gainsboro}#GanttAxis .sunday{fill:#fdd}#GanttAxis .weekday{fill:whitesmoke}#GanttAxis .date{stroke:white}#BurnDown{width:100%;height:350px;background-color:#f5f5f5;border-radius:20px}#BurnDown .now{stroke:red}#BurnDown .total{fill:none;stroke:green}#BurnDown .planned{fill:none;stroke:gray}#BurnDown .earned{fill:none;stroke:orange}#BurnDown .total circle{fill:green}#BurnDown .planned circle{fill:gray}#BurnDown .earned circle{fill:orange}#BurnDownDetails>tbody>tr:hover{background-color:#f5f5f5;cursor:pointer}#BurnDownDetails>tbody>tr>td{padding:6px}#BurnDownDetails>tbody>tr>td.warning{font-weight:bold;color:#f00}#BurnDownDetails>tbody>tr>td.difference{font-size:1.3em;font-weight:bold;color:#00f;background-color:#e0ffff}#BurnDownDetails>tbody>tr>td.difference.warning{color:#f00;background-color:#ffccd5}#BurnDownDetails .user-info{margin:5px;padding:8px;font-weight:bold;background-color:#eee8aa}#BurnDownDetails .items{padding:5px 0 5px 20px}#BurnDownDetails .items a{color:#000;text-decoration:none}#BurnDownDetails .items a:hover{color:#00f;text-decoration:underline}#TimeSeries{width:100%;height:450px;background-color:#f5f5f5;border-radius:20px}#TimeSeries .surface{stroke:white}#TimeSeries .index{fill:black}#KambanBody .kamban-row{border-bottom:dotted 1px #c0c0c0}#KambanBody .kamban-container>div{min-height:30px}#KambanBody .kamban-container.hover{background-color:#f5f5f5}#KambanBody .kamban-container .kamban-item:last-child{margin:3px 3px 30px 3px}#KambanBody .kamban-item{margin:3px;padding:4px 16px 4px 5px;background-color:#fafad2;border:solid 1px #c0c0c0;position:relative;cursor:pointer;border-radius:5px}#KambanBody .kamban-item:hover{background-color:#fff;border:solid 1px #ffa500}#KambanBody .kamban-item.changed{font-weight:bold;background-color:#ff0;border:solid 1px #ffa500}#KambanBody .kamban-item .ui-icon{position:absolute;top:0;right:0}#ImageLib{float:left}#ImageLib .item{width:250px;height:250px;float:left;margin:10px 10px 0 0;padding:10px;border:solid 1px #c0c0c0;position:relative;overflow:hidden}#ImageLib .item .image{width:100%;float:left;margin:5px 0 0 0}#ImageLib .item .delete-image{float:left;position:absolute;right:5px;bottom:5px}#RecordHeader{width:100%;float:left;margin:0 0 5px 0}#RecordInfo{float:left;padding:6px 0 0 0}#RecordInfo div{float:left;margin-right:50px}#RecordInfo div p{float:left;margin-right:5px}#RecordInfo div p .elapsed-time{float:left;padding:0 5px;font-weight:bold;background-color:#eee;border-radius:2px}#RecordSwitchers{float:right}#RecordSwitchers>*{float:left}#RecordSwitchers .current{height:26px;display:block;float:left;margin:0 1px 0 0;padding:5px;border-radius:5px}#TemplateTabsContainer{width:100%;float:left}#Editor{width:100%;float:left;clear:both}#EditorTabsContainer{width:73%;float:left;margin:0 0 20px 0}#EditorTabsContainer.max{width:100%}#MailEditorTabsContainer{width:100%;float:left;margin:0 0 20px 0;border:none}#EditorComments{width:27%;float:right;margin:0 0 15px 0;padding:0 0 0 5px}#EditorComments .title-header{margin:3px 10px 8px 0}#CommentField{margin:0 0 5px 0}#OutgoingMailsForm{width:73%;float:left}#OutgoingMailsForm>.item{width:100%;float:left;position:relative;border-radius:10px}#OutgoingMailsForm .content{width:100%;float:left;margin:5px 0 20px 0;padding:10px 0 0 0;border:solid 1px #c0c0c0;border-top:none;border-radius:0 0 10px 10px/0 0 10px 10px}#DropDownSearchDialogForm{width:100%;padding:0 20px}#ProcessTabsContainer{margin:0 20px 10px 20px;clear:both}#StatusControlTabsContainer{margin:0 20px 10px 20px;clear:both}#StatusControlColumnHash .column-control-types{margin:0 0 0 10px}#ViewTabsContainer{margin:0 20px 10px 20px;clear:both}#ExportTabsContainer{margin:0 20px 10px 20px;clear:both}#EditorDetailTabsContainer{margin:0 20px 10px 20px;clear:both}#ColumnAccessControlTabsContainer{margin:0 20px 10px 20px;clear:both}#SearchResults{width:80%;float:left;margin:0 100px}#SearchResults .count{float:left;margin:0 0 10px 0}#SearchResults .count .label{height:26px;display:block;float:left;margin:0 5px 5px 0;padding:5px 10px;background:#dcdcdc;border-radius:5px}#SearchResults .count .data{height:26px;display:block;float:left;margin:0 5px 5px 0;padding:5px}#SearchResults .result{width:100%;float:left;padding:15px;border:solid 1px #fff;clear:both}#SearchResults .result>ul{display:block;float:left;clear:both}#SearchResults .result>h3{display:block;float:left;margin:5px 0;clear:both}#SearchResults .result>h3>a{font-size:1.3em;font-weight:bold}#SearchResults .result>p{display:block;float:left;clear:both}#SearchResults .result:hover{border:solid 1px #ffa500;cursor:pointer}#MainCommandsContainer{width:100%;height:47px;padding:7px 0 0 0;background-color:rgba(0,0,0,.65);position:fixed;left:0;bottom:30px;z-index:11}#MainCommands{text-align:center}#MainCommands>button{display:inline;float:none;margin:2px 4px}#ApiEditorCommands{padding:0 5px 200px 140px}#ApiEditorCommands>*{margin-right:10px}#BottomMargin{height:100px;clear:both}#Video{width:640px;height:480px;display:block;float:left;margin:0 16px}#Canvas{display:none}#Footer{width:100%;height:30px;display:block;padding:5px 10px;text-align:right;background-color:#000;position:fixed;left:0;bottom:0;z-index:10}#Footer a{color:#fff;text-decoration:none}#Versions{width:500px;margin:150px auto 20px auto;padding:50px;background-color:#f5f5f5;border-radius:10px}#Versions span{margin:10px;line-height:30px}.template{width:100%;display:block;float:left}.template-selectable{width:340px;display:block;float:left}.template-viewer-container{width:100%;display:block;float:right;margin:0 0 0 -340px}.template-viewer{margin:0 0 0 340px}.template-viewer .description{margin:10px 0 8px 0;padding:5px;background-color:#fefedd;border:solid 1px #c0c0c0;border-radius:5px}.template-viewer .samples-displayed{margin:0 0 8px 0;padding:5px;color:#f00;background-color:#ffc0cb;border:solid 1px #f00;border-radius:5px}.template-tab-container{min-height:600px}.main-form{clear:both}.nav-sites{margin:0 -10px;clear:both}.nav-site{width:220px;height:70px;float:left;margin:10px;position:relative;top:0;left:0;border-radius:5px}.nav-site .heading{width:50px;height:9px;position:absolute;top:-10px;left:5px;border-radius:3px 3px 0 0/3px 3px 0 0}.nav-site .stacking1{width:220px;height:70px;border-bottom:solid 1px #c0c0c0;border-right:solid 1px #c0c0c0;position:absolute;top:1px;left:1px;border-radius:5px}.nav-site .stacking2{width:220px;height:70px;border-bottom:solid 1px #c0c0c0;border-right:solid 1px #c0c0c0;position:absolute;top:4px;left:4px;border-radius:5px}.nav-site a{width:100%;height:100%;display:block;padding:10px 3px 3px 10px;overflow:hidden;word-wrap:break-word;text-decoration:none}.nav-site.has-image a{padding:10px 3px 3px 65px}.nav-site span.title{margin-left:5px}.nav-site.to-parent{height:36px;background-color:#fff}.nav-site.to-parent a{padding:9px 3px 3px 30px}.nav-site.to-parent.has-image a{padding:9px 3px 3px 35px}.nav-site.to-parent .ui-icon{position:absolute;top:9px;left:9px}.nav-site .site-image-thumbnail{position:absolute;top:8px;left:8px;border-radius:8px}.nav-site .site-image-icon{position:absolute;top:4px;left:8px;border-radius:8px}.nav-site .conditions{font-size:.75em;color:#000;position:absolute;right:1px;bottom:1px}.nav-site .conditions span{display:block;float:left;margin:2px 2px 2px 0;padding:2px 5px;background-color:#eee;border-radius:2px}.nav-site .conditions span.overdue{color:#fff;background-color:#f00}.nav-site .conditions span.elapsed-time.old{color:#c0c0c0}.error-page{padding:30px 50px;border-top:dotted 1px #808080}.error-page-title{margin:0 0 20px 0;padding:10px 0;font-weight:bold;color:#f00;border-bottom:dotted 1px #f00}.error-page-message{margin:15px 0 0 0;padding:5px 20px;font-weight:bold;color:#fff;background-color:#808080}.error-page-action{margin:5px 0 0 0;padding:5px 10px;color:#c0c0c0;background-color:#dcdcdc}.error-page-action em{margin:10px;color:#000}.error-page-stacktrace{margin:5px 0 0 0;padding:5px 20px;background-color:#f5f5f5}.fieldset.enclosed{margin:0 0 10px 0;padding:10px;border:solid 1px #c0c0c0;clear:both}.fieldset.enclosed-half{width:380px;float:left;margin:0 0 10px 0;padding:10px;border:solid 1px #c0c0c0}.fieldset.enclosed-thin{margin:0 0 10px 0;padding:5px 5px 5px 10px;border:solid 1px #c0c0c0;clear:both}.fieldset.enclosed-thin [class*="field-auto"]{height:35px}.fieldset.enclosed-auto{float:left;margin:0 0 10px 10px;padding:5px 5px 5px 10px;border:solid 1px #c0c0c0}.fieldset[class^="enclosed"]>legend{margin:0 0 0 10px;font-weight:bold}.command-field{padding:10px 5px 5px 136px;text-align:center;clear:both}.command-field>button{display:block;float:left;margin:2px 4px}.command-center{padding:5px 5px 5px 5px;text-align:center;clear:both}.command-center>button{display:inline;float:none;margin:2px 4px}.command-left{float:left;padding:5px 5px 5px 5px;clear:both}.command-left>*{display:block;float:left}.command-left>button{margin:2px 4px}.command-left>.ui-icon{margin:7px 3px 0 15px}.command-right{padding:5px 5px 5px 5px;text-align:right;clear:both}.command-right>button{display:inline;float:none;margin:2px 4px}.field-normal{width:340px;height:45px;float:left;padding:0 20px 10px 0}.field-normal>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-normal>.field-control{width:100%;float:right}:not(td)>div.field-normal .container-normal{width:auto;margin-left:120px}td>.field-normal,td>.field-wide{width:100%;padding:0}.field-normal>.buttons{padding:3px 10px}.field-normal .control-text{height:30px}.field-wide{width:100%;min-height:45px;float:left;padding:0 10px 10px 0;clear:both}.field-wide>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-wide>.field-control{width:100%;float:right}:not(td)>div.field-wide .container-normal{margin-left:120px}.field-markdown{width:100%;min-height:45px;float:left;padding:0 10px 10px 0;clear:both}.field-markdown>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-markdown>.field-control{width:100%;float:right}:not(td)>div.field-markdown .container-normal{margin-left:120px}.field-textarea{width:100%;min-height:45px;float:left;padding:0 10px 10px 0;clear:both}.field-textarea>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-textarea>.field-control{width:100%;float:right}:not(td)>div.field-textarea .container-normal{margin-left:120px}.field-auto{width:auto;height:45px;float:left;margin-right:35px;padding:0 10px 10px 0}.field-auto>.field-label{width:120px;float:left;padding:7px 7px 7px 0;text-align:right}.field-auto>.field-control{width:auto;float:left}.field-auto-thin{width:auto;height:45px;float:left;margin:0 5px;padding:0 10px 10px 0}.field-auto-thin>.field-label{float:left;padding:7px 7px 7px 0;text-align:right}.field-auto-thin>.field-control{width:auto;float:left}.field-auto-thin select{max-width:120px}.field-vertical{width:330px;height:100%;float:left;padding:0 20px 20px 0}.field-vertical>.field-label{width:100%;float:left;margin-right:-120px;padding:5px 10px;text-align:center}.field-vertical>.field-control{width:100%;float:left;clear:both}.field-label{overflow:hidden}.field-label .required:after{margin-left:3px;color:#f00;content:'*'}.field-control .unit{display:block;float:left;padding:5px 0 0 5px}.field-section{width:100%;display:block;float:left;margin:15px;padding:2px 5px;font-weight:bold;border-bottom:solid 1px #c0c0c0;clear:both}.container-normal{position:relative}.container-left{width:340px;float:left;margin-right:-340px;padding:0 0 15px 0;position:relative}.container-right{width:100%;float:right;position:relative}.container-right>*{display:block;margin-left:340px}.control-text{width:100%;min-height:30px;display:block;padding:6px 4px 2px 4px;color:#000;background:#f5f5f5;border:solid 1px #c0c0c0;overflow:hidden;border-radius:5px}.control-textbox{width:100%;height:30px;padding:4px;border:solid 1px #c0c0c0;border-radius:5px}.control-textbox.with-unit{width:70%;display:block;float:left}.control-textbox.anchor{width:100%;height:30px;padding:4px;border:solid 1px #c0c0c0;border-radius:5px;z-index:0}.control-textarea{width:100%;height:100px;padding:4px 4px 4px 6px;border:solid 1px #c0c0c0;border-radius:5px}.control-attachments+label.error{height:22px;position:absolute;top:50px}.control-attachments-upload{width:100%;display:block;float:left;padding:25px 0;text-align:center;border:dotted 2px #d19405;border-radius:3px}.control-attachments-items{width:100%;display:block;float:left}.control-attachments-item{width:100%;display:block;float:left;margin:5px 0 0 0;padding:5px 10px;text-align:left;border:solid 1px #d19405;border-radius:5px}.progress-bar{width:100%;height:30px;display:block;float:left;margin:5px 0 0 0;vertical-align:top;border:solid 1px #d19405;overflow:hidden;border-radius:5px}.progress-bar>div{width:0;height:100%;line-height:22px;color:#fff;background-color:#fece2f;border-radius:3px}.already-attachments{background-color:#fece2f}.preparation-delete{background-color:#f5f5f5;border:solid 1px #c0c0c0}.preparation-delete>a{color:#c0c0c0}.show-file{display:block;float:left;margin:0}.file-name{display:block;float:left}.delete-file{display:block;float:right;margin:2px -5px 0 0}.field-control .control-markup{width:100%;min-height:100px;float:left;padding:4px 25px 4px 6px;color:#000;background:#f5f5f5;border:solid 1px #c0c0c0;border-radius:5px}.md{width:100%;float:left;line-height:1.5em;font-family:Terminal;word-wrap:break-word;word-break:break-all}.md>*{float:left;clear:both}.md h1{margin:10px 0 10px 0;font-weight:bold}.md h1:not(:first-child){margin:20px 0 10px 0}.md h2{margin:5px 0 8px 0;font-weight:bold}.md h2:not(:first-child){margin:20px 0 8px 0}.md h3{margin:3px 0 6px 0;font-weight:bold}.md h3:not(:first-child){margin:10px 0 6px 0}.md h4{margin:3px 0 4px 0;font-weight:bold}.md h4:not(:first-child){margin:10px 0 4px 0}.md h5{margin:3px 0 2px 0;font-weight:bold}.md h5:not(:first-child){margin:10px 0 2px 0}.md h6{margin:3px 0 2px 0;font-weight:bold}.md h6:not(:first-child){margin:10px 0 2px 0}.md hr{float:none;clear:both}.md ol{margin:0 10px 10px 32px;list-style-type:decimal}.md p{margin:0 0 10px 0;clear:both}.md table{width:auto;margin:0 0 10px 0;background-color:#fff}.md td{padding:5px 10px;border:solid 1px #c0c0c0}.md th{padding:5px 10px;font-weight:bold;border:solid 1px #c0c0c0}.md tbody tr:nth-child(odd){background-color:#f5f5f5}.md ul{margin:0 10px 10px 32px;list-style-type:disc}.control-markdown{width:100%;display:none;padding:4px 4px 4px 6px;border:solid 1px #c0c0c0;border-radius:5px}.control-dropdown{width:100%;height:30px;padding:4px;border:solid 1px #c0c0c0;border-radius:5px}.control-spinner{width:auto;height:22px;display:block;float:left;padding:1px;color:#000}.control-checkbox{display:block;float:left;margin:8px 0}.control-checkbox~label{display:block;float:left;margin:7px 5px 0 7px}.control-checkbox+.ui-icon.ui-icon-info{display:block;float:left;margin:7px -7px 0 0}.field-normal .control-checkbox+label{width:175px}_::-webkit-full-page-media,_:future,:root .field-normal .control-checkbox+label{width:172px}.control-radio{display:block;float:left;margin:8px 0}.control-radio+label{display:block;float:left;margin:4px 10px 5px 7px}.control-slider{width:30px;float:left;margin:8px 0 0 12px}.control-slider-ui{width:140px;float:left;margin:11px 0 0 5px}.container-selectable .wrapper{width:100%;min-height:300px;display:block;float:left;background-color:#f5f5f5;border:solid 1px #c0c0c0;overflow:auto;border-radius:5px}.control-selectable{width:100%;display:block;float:left;padding:5px 10px 5px 5px;list-style-type:none;touch-action:pan-y}.control-selectable li{width:100%;min-height:24px;margin:3px;padding:2px 5px;border-radius:5px}.control-basket{margin-left:120px;padding:5px 5px 0 5px;background-color:#f5f5f5;border:solid 1px #c0c0c0;border-radius:5px}.control-basket>li{display:block;float:left;margin:0 5px 5px 0;padding:3px 5px;border-radius:5px}.control-basket>li>span{display:block;float:left;z-index:2}.comment{width:100%;display:block;float:left;margin:0 0 5px 0;padding:5px 10px 10px 20px;background:#fafad2;border:solid 1px #c0c0c0;position:relative;clear:both}.comment>*{display:block;float:left}.comment>.time{float:left;margin:0 0 8px -10px;margin-right:10px}.comment>.body{width:100%;clear:both}.comment>.button.edit{position:absolute;top:3px;right:20px;cursor:pointer}.comment>.button.delete{position:absolute;top:3px;right:5px;cursor:pointer}.comment>.control-markup{width:100%}.comment>.control-markdown{width:100%;display:none}.user{float:left}.user>span{display:block;float:left;font-weight:bold}.dept{float:left}.dept>span{display:block;float:left;font-weight:bold}.both{clear:both}.hidden{display:none}.right{float:right}.right-align{text-align:right;text-align-last:right}.tooltip{display:none;position:absolute}.no-border{border:none}.grid{margin:0 0 10px 0}.grid.fixed{table-layout:fixed}.grid>thead>tr>caption{margin:0 0 5px 0}.grid>thead>tr>th{padding:6px;vertical-align:middle;border-top:solid 1px transparent;border-bottom:solid 1px transparent;border-left:solid 1px transparent;border-right:solid 1px #fff;word-wrap:break-word}.grid>thead>tr>th>div{width:100%;float:left;text-align:center;z-index:2}.grid>thead>tr>th span{display:block;float:left}.grid>thead>tr:first-child>th:first-child{border-radius:10px 0 0 0/10px 0 0 0}.grid>thead>tr:first-child>th:last-child{border-right:solid 1px transparent;border-radius:0 10px 0 0/0 10px 0 0}.grid>thead>tr>th.sortable:hover{cursor:pointer}.grid>tbody>tr>td{max-width:300px;border-left:dotted 1px #c0c0c0;border-right:dotted 1px #c0c0c0;word-wrap:break-word}.grid>tbody>tr.message-row>td{padding:0;text-align:center}.grid>tbody>tr [class*="status-"]{padding:0 5px;font-weight:bold;border:solid 1px #c0c0c0;border-radius:3px}.grid>tbody>tr>th{padding:6px;vertical-align:middle;font-weight:normal;background-color:#dcdcdc;border-top:solid 1px #fff;border-bottom:solid 1px #fff;border-left:solid 1px transparent;border-right:solid 1px transparent;word-wrap:break-word}.grid-row{background-color:#fff;border-bottom:solid 1px #c0c0c0}.grid-row td{overflow:hidden}.grid-row .comment{min-width:200px;max-height:100px;margin:0 0 3px 0;padding:3px 6px 3px 15px;background:#fafad2;border:solid 1px #fff;clear:both;overflow:hidden}.grid-row .comment.one-third{max-height:306px}.grid-row .comment.half{max-height:151px}.grid:not(.not-link) .grid-row:hover{background-color:#f5f5f5;cursor:pointer}.grid-row:hover .comment{background-color:#ffffe0}.grid-row p{float:left}.grid-row p.body{clear:both}.grid-row[data-history]{background-color:#d3d3d3}.grid-title-body{min-width:200px;max-height:306px;margin:0 0 3px 0;padding:3px 6px;background:inherit;border:solid 1px transparent;clear:both;overflow:hidden}.grid-title-body>.body{width:100%}.grid-title-body>.title+.body{padding:8px 0 0 10px}.links{padding:0 10px}.link-creations button{display:block;float:left;margin:0 10px 0 0}.text{width:250px;display:block;float:left;border:solid 1px #c0c0c0}.datepicker{display:block;float:left;border:solid 1px #c0c0c0}.dropdown{display:block;float:left;border:solid 1px #c0c0c0}[class*="limit-"]{margin-left:10px;padding:0 5px}.limit-warning1{color:#f00}.limit-warning2{color:#f00;background-color:#ffccd5}.limit-warning3{color:#fff;background-color:#f00}.message{width:100%;text-align:center;position:fixed;left:0;bottom:78px;z-index:100}.message .body{margin-bottom:4px;position:relative;border-radius:20px}.message .close{background-color:#fff;position:absolute;top:11px;right:8px;cursor:pointer;border-radius:10px}.message-dialog{width:100%;display:block;float:left;margin:0 auto;text-align:center}.message-form-bottom{width:600px;margin:0 auto;text-align:center}.alert-error{min-height:32px;display:block;padding:5px;color:#fff;background-color:rgba(255,0,0,.9);border:solid 1px #f00}.alert-success{min-height:32px;display:block;padding:5px;color:#fff;background-color:rgba(0,128,0,.9);border:solid 1px #008000}.alert-warning{min-height:32px;display:block;padding:5px;color:#000;background-color:#ff0;border:solid 1px #ff0}.alert-information{min-height:32px;display:block;padding:5px;color:#fff;background-color:#00f;border:solid 1px #00f}label.error{width:100%;display:block;float:left;padding:0 5px;color:#f00;background-color:#fff;border-top:none;top:-5px;left:0;border-radius:0 0 5px 5px/0 0 5px 5px;z-index:2}.ui-spinner>label.error{margin-top:3px}.error{border:solid 1px #f00}.error+.ui-widget.ui-state-default.ui-multiselect{border:solid 1px #f00}.with-unit+label.error{width:70%;position:absolute;top:25px}.button-edit-markdown{position:absolute;top:5px;right:5px;cursor:pointer;z-index:1}.comment>.button-edit-markdown{top:6px;right:20px}.button-delete-address{cursor:pointer}.button-right-justified{float:right}.status-new{background:#fff}.status-preparation{color:#fff;background:#ff8c00}.status-inprogress{color:#fff;background:#008000}.status-review{background:#ff0}.status-closed{color:#fff;background:#00f}.status-rejected{color:#fff;background:#808080}.always-hidden{display:none}h3.title-header{height:40px;padding:10px 20px;text-align:center;background-color:#dcdcdc;border:solid 1px #a9a9a9;border-radius:10px 10px 0 0/10px 10px 0 0}.outgoing-mail .dialog{padding:0 !important}.outgoing-mail .ui-dialog-titlebar{display:none}.svg-work-value{width:50px;height:40px}.svg-work-value rect:nth-of-type(1){fill:gainsboro}.svg-work-value rect:nth-of-type(2){fill:darkseagreen}.svg-progress-rate{width:50px;height:40px}.svg-progress-rate.warning text{fill:red}.svg-progress-rate rect:nth-of-type(1){fill:gainsboro}.svg-progress-rate rect:nth-of-type(2){fill:gray}.svg-progress-rate rect:nth-of-type(3){fill:darkseagreen}.svg-progress-rate.warning rect:nth-of-type(3){fill:#ffccd5}.svg-kamban-aggregation-view{width:100%;height:20px}.svg-kamban-aggregation-view rect{height:20px;fill:darkseagreen}.svg-crosstab{width:100%;height:20px}.svg-crosstab rect{height:20px;fill:darkseagreen}.axis{fill:none;stroke:gray;shape-rendering:crispEdges}.h2{margin:0 0 5px 0;padding:0}.h3{margin:0 0 5px 10px;padding:0}.h4{margin:0 0 5px 20px;padding:0}.h5{margin:0 0 5px 30px;padding:0}.h6{margin:0 0 5px 40px;padding:0}.h2>h2{padding:5px 0;font-weight:bold;border-bottom:solid 1px #c0c0c0}.h3>h3{font-weight:bold}.h4>h4{font-weight:bold}.h5>h5{font-weight:bold}.h6>h6{font-weight:bold}.w50{width:50px}.w100{width:100px}.w150{width:150px}.w200{width:200px}.w250{width:250px}.w300{width:300px}.w350{width:350px}.w400{width:400px}.w450{width:450px}.w500{width:500px}.w550{width:550px}.w600{width:600px}.h100{height:100px}.h150{height:150px}.h200{height:200px}.h250{height:250px}.h300{height:300px}.h350{height:350px}.h400{height:400px}.h450{height:450px}.h500{height:500px}.h550{height:550px}.h600{height:600px}.m-l10{margin-left:10px}.m-l20{margin-left:20px}.m-l30{margin-left:30px}.m-l40{margin-left:40px}.m-l50{margin-left:50px}.paragraph{padding:3px 3px 3px 10px}.dialog{display:none;padding:15px 0 10px 0 !important}.dialog .fieldset{margin:0 10px 10px 10px}.link span{margin-right:5px}.link span.bold{font-weight:bold;cursor:pointer}.histories-form{padding:20px}.ui-widget input,.ui-widget select,.ui-widget button{font-family:Hiragino Kaku Gothic Pro,"Meiryo UI",sans-serif}.ui-widget textarea{line-height:1.5em;font-family:Terminal}.ui-widget{font-size:1em}.ui-button{padding:4px 4px 4px 2px !important}.ui-dialog{overflow:visible !important}.ui-icon.a{float:left;margin:6px 0 0 0}.ui-spinner{display:block;float:left;background:#fff;max-height:46px}.ui-widget.ui-state-default.ui-multiselect{height:30px;background:#fff;border:solid 1px #c0c0c0;overflow:hidden;border-radius:5px}.ui-multiselect-checkboxes{min-height:300px}.ui-multiselect-checkboxes input{margin:0 5px}.ui-corner-all.ui-state-hover{border-radius:2px}div.field-control .ui-multiselect.ui-state-disabled{background-color:#f5f5f5;opacity:1}.height-auto{max-height:none !important}.focus-inform{background-color:#fff !important;border:solid 1px #ffa500 !important}.menu-negative{border-left:solid 1px #fff;border-right:solid 1px #fff;position:absolute;z-index:10}.menu-negative>li{width:100%;display:block;float:left;border-top:dotted 1px #fff;cursor:pointer;clear:both}.menu-sort{border-left:solid 1px #fff;border-right:solid 1px #fff;position:absolute;border-radius:0 0 10px 10px/0 0 10px 10px;z-index:10}.menu-sort>li{width:100%;display:block;float:left;border-top:dotted 1px #fff;cursor:pointer;clear:both}.menu-sort>li.ui-menu-divider{height:initial;font-size:initial}.menu-sort>li.grid-header-filter .ui-icon{position:initial}.menu-sort>li:not(.grid-header-filter) div.field-control>*{border:solid 1px #c0c0c0}.current-time{position:absolute;top:9px;right:-17px;cursor:pointer;z-index:10}.current-user{position:absolute;top:9px;right:-17px;cursor:pointer;z-index:10}.current-dept{position:absolute;top:9px;right:-17px;cursor:pointer;z-index:10}input:focus{background-color:#ffc}select:focus:not(.has-css){background-color:#ffc}textarea:focus{background-color:#ffc}.ssoLoginMessage{margin:10px;padding:6px;border-top:solid 1px #c0c0c0}#EnterPriseBanner{width:238px;position:fixed;right:8px;bottom:280px;z-index:3}#SupportBanner{width:238px;position:fixed;right:8px;bottom:180px;z-index:3}#CasesBanner{width:238px;position:fixed;right:8px;bottom:80px;z-index:3} \ No newline at end of file +@charset "utf-8";*{box-sizing:border-box}html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-style:normal;font-weight:normal;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}input,textarea{margin:0;padding:0}ol,ul{list-style:none}table{border-collapse:collapse;border-spacing:0}caption,th{text-align:left}a:focus{outline:none}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.both{clear:both}img{max-width:100%;height:auto;width:auto}::-webkit-input-placeholder{color:#c0c0c0}:-moz-placeholder{color:#c0c0c0;opacity:1}::-moz-placeholder{color:#c0c0c0;opacity:1}:-ms-input-placeholder{color:#c0c0c0}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}input[type="number"]{-moz-appearance:textfield}body{min-width:1200px;font-size:.75em;font-family:Hiragino Kaku Gothic Pro,"Meiryo UI",sans-serif;clear:both}h1{clear:both}h2{clear:both}h3{clear:both}legend{cursor:pointer}legend>*{display:block;float:left}label{position:relative;cursor:pointer;z-index:2}input{background-color:#fff;position:relative;z-index:2}select{position:relative;z-index:2}table{width:100%;border:0;border-collapse:collapse;clear:both}td{padding:3px;vertical-align:top;color:#000}td.right-align>p{float:right}pre{line-height:1.5em;font-family:Terminal;word-wrap:break-word;word-break:break-all;white-space:pre-wrap}#Logo{padding:3px 0}#CorpLogo{display:block;float:left;margin:3px 0 0 0}#ProductLogo{display:block;float:left;padding:0 0 0 5px;font-size:26px;font-weight:bold;color:#696969;text-decoration:none}#PortalLink{position:relative;top:-38px;right:40px;float:right}#LoginFieldSet{width:500px;margin:150px auto 20px auto;padding:50px;background-color:#f5f5f5;border-radius:10px}#LoginCommands{text-align:right;clear:both}#Demo{width:500px;margin:0 auto}#DemoFields{padding:20px 10px 10px 10px}#SearchPermissionElements{margin-left:15px}#Breadcrumb{float:left;margin:0 0 5px 0}#Breadcrumb .item{display:block;float:left;padding:3px 5px}#Breadcrumb .item.trashbox{display:block;float:left;color:#fff;background-color:#f00;border-radius:3px}#Breadcrumb .separator{margin:0 0 0 8px}#Guide>div{width:100%;display:block;float:left;margin:0 0 5px 0;padding:5px 10px;background:#fafad2;border:solid 1px #c0c0c0;position:relative;clear:both;border-radius:5px}#CopyToClipboards>.display-control{float:left;cursor:pointer}#Header{width:100%;float:left;padding:0 6px;border:none;position:relative;clear:both}#Navigations{height:30px;margin:0 0 5px 0;padding:0 5px 0 15px;border:none;top:0;right:5px;border-radius:20px 5px 5px 20px;float:right}#NavigationMenu{float:left;margin-right:5px}#NavigationMenu>li{width:158px;height:30px;display:block;float:left;position:relative}#NavigationMenu>li>div{height:30px;text-align:center;line-height:30px;cursor:pointer}#NavigationMenu>li>div>a{height:30px;display:block;text-decoration:none}#NavigationMenu .menu{width:158px;display:none;border-top:none !important;position:absolute;top:30px;right:0;border-radius:0 0 5px 5px;z-index:3}#NavigationMenu .menu>li>a{display:block;text-decoration:none}#NavigationMenu .menu>li>a.ui-state-active{font-weight:normal;text-decoration:none}#TemplateDialog>div{padding:0 15px;overflow:hidden}#SearchField{float:left;margin:3px 0;color:#000}#Search{height:24px}#SwitchUserInfo{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;color:#fff;background-color:#00f;border-radius:7px}#SwitchUserInfo>a{width:100%;display:block;float:left;color:#fff;text-decoration:none}#ExcessLicenseWarning{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;color:#fff;background:#f00;border-radius:7px}#PublishWarning{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;background:#f00;border-radius:7px}#PublishWarning>a{width:100%;display:block;float:left;color:#fff;text-decoration:none}#LockedWarning{width:100%;display:block;float:left;margin:0 10px 5px 0;padding:5px 10px;background:#f00;border-radius:7px}#LockedWarning>div{width:100%;display:block;float:left;color:#fff;text-decoration:none}#Application{width:100%;float:left;margin:10px 0 0 0;padding:0 10px 120px 10px;position:relative;clear:both}#Application>.site-image-icon{display:block;float:left;margin:0 10px 0 0}#StartGuide{width:100%;display:block;float:left;margin:0 0 10px 0;padding:50px 0 0 0;background-color:#f5f5f5;position:relative;border-radius:10px}#StartGuide>#StartGuideContents{width:900px;margin:0 auto}#StartGuide>#StartGuideContents>a{width:150px;display:block;float:left;margin:0 37px;padding:5px;text-align:center;border-radius:5px}#StartGuide>#StartGuideContents>a:hover{background-color:#fff}#StartGuide>#StartGuideContents>a>*{display:block;text-align:center;clear:both}#StartGuide>#StartGuideContents>a>img{width:50px;margin:5px 50px}#StartGuide>#DisableStartGuideField{display:block;float:left;margin:50px 0 0 20px;clear:both}#StartGuide>.ui-icon{position:absolute;top:10px;right:10px;cursor:pointer}#SiteImageIconContainer{float:left}#SiteImageIconContainer>*{margin:0 5px 0 0}#HeaderTitleContainer{float:left;margin:0 0 10px 0}#HeaderTitle{font-size:20px;font-weight:bold;color:#d2691e}#Notes>*{width:100%;float:left;margin:0 10px 5px 0}#Notes>.history{width:100%;display:block;float:left;padding:5px 10px;color:#fff;background-color:#00f;border-radius:7px}#Notes>.readonly{width:100%;display:block;float:left;padding:5px 10px;color:#fff;background-color:#ffa500;border-radius:7px}#ViewSelectorField{position:absolute;top:-10px;right:0}#ViewFilters{width:100%;float:left;margin:0 0 5px 0;padding:5px 5px 2px 5px;border:solid 1px #c0c0c0;border-radius:5px}#ViewFilters.reduced{width:auto;padding:0;border:none}#ViewFilters>.field-auto-thin{height:32px;float:left;padding:0}#ViewFilters_Reset{display:block;float:left;margin:0 20px 0 0}#ViewFilters>.display-control{float:left;margin:0 5px 0 0;padding:5px 10px 5px 0;font-weight:bold;cursor:pointer}#ViewFilters .ui-icon.ui-icon-info{transform:scale(1,-1)}#FilterButton{display:block;float:left}#Aggregations{width:100%;float:left;margin:0 0 5px 0;padding:3px 5px 5px 5px;border:solid 1px #c0c0c0;border-radius:5px}#Aggregations.reduced{width:auto;padding:0;border:none}#Aggregations .label{height:26px;display:block;float:left;margin:2px 5px 0 0;padding:5px 10px;background:#dcdcdc;border-radius:5px}#Aggregations .label.overdue{font-weight:bold;color:#fff;background-color:#f00;cursor:pointer}#Aggregations .data{height:26px;display:block;float:left;margin:2px 5px 0 0;padding:5px}#Aggregations .data.overdue{color:#f00;cursor:pointer}#Aggregations em{display:block;float:left;margin-right:5px;font-weight:bold}#Aggregations>.display-control{float:left;margin:0 5px 0 0;padding:5px 10px 5px 0;font-weight:bold;cursor:pointer}#SitePackagesSelectable span.include-data{margin:0 0 0 10px;color:#f00}#CalendarDate{margin-right:10px}#CalendarBody table{table-layout:fixed}#CalendarBody thead th{padding:5px;text-align:center;border:solid 1px #c0c0c0}th.calendar-header{text-align:center;background-color:#fff}#CalendarBody .saturday{background-color:#add8e6}#CalendarBody .sunday{background-color:#ffc0cb}#CalendarBody td{padding:0;border:solid 1px #c0c0c0}#CalendarBody td>div{min-height:50px;padding:5px}#CalendarBody td.hover{background-color:#f5f5f5}#CalendarBody .other-month{background-color:#dcdcdc}#CalendarBody .today{border:solid 2px #00f;z-index:20}#CalendarBody .item{height:25px;margin:5px 0 0 0;background-color:#fafad2;border:solid 1px #c0c0c0;border-radius:3px}#CalendarBody .item.hover{background-color:#fff;border:solid 1px #ffa500}#CalendarBody .item.changed{font-weight:bold;background-color:#ff0;border:solid 1px #ffa500}#CalendarBody .item .connection{width:14px;height:25px;background-color:#fafad2;border-top:solid 1px #c0c0c0;border-bottom:solid 1px #c0c0c0;position:relative;top:-1px;left:-14px}#CalendarBody .item .connection.hover{background-color:#fff;border-top:solid 1px #ffa500;border-bottom:solid 1px #ffa500}#CalendarBody .item .connection.changed{font-weight:bold;background-color:#ff0;border-top:solid 1px #ffa500;border-bottom:solid 1px #ffa500}#CalendarBody .item .title{padding:5px 0;position:absolute;overflow:hidden;white-space:nowrap;z-index:30}#CalendarBody .item .title.sub{display:none}#CalendarBody .dragging{height:25px;padding:5px;background-color:#fafad2;border-radius:3px;z-index:50}#CalendarBody .dummy{height:25px;margin:5px 0 0 0}#Crosstab .crosstab-row{border-bottom:dotted 1px #c0c0c0}#Crosstab .saturday{background-color:#eee}#Crosstab .sunday{background-color:#fee}#CrosstabMonth{margin-right:10px}#Gantt{width:100%;background-color:#f5f5f5;border-radius:20px}#Gantt .saturday{fill:#eee}#Gantt .sunday{fill:#fee}#Gantt .date{stroke:white}#Gantt .now{stroke:red}#Gantt .planned rect{cursor:pointer;fill:gainsboro}#Gantt .planned rect.summary{cursor:auto}#Gantt .earned rect{cursor:pointer;fill:darkseagreen}#Gantt .earned rect.summary{cursor:auto}#Gantt rect.delay{fill:#ffccd5}#Gantt rect.completed{fill:lightsteelblue}#Gantt .title text{cursor:pointer}#Gantt .title text.delay{fill:red}#Gantt .title text.summary{font-size:1.2em;font-weight:bold;cursor:auto}#GanttStartDate{margin-right:10px}#GanttAxis{width:calc(100% + 20px);height:50px;margin-left:-10px;margin-top:-25px;background-color:rgba(255,255,255,.5);position:sticky;left:0;bottom:75px}#GanttAxis .saturday{fill:gainsboro}#GanttAxis .sunday{fill:#fdd}#GanttAxis .weekday{fill:whitesmoke}#GanttAxis .date{stroke:white}#BurnDown{width:100%;height:350px;background-color:#f5f5f5;border-radius:20px}#BurnDown .now{stroke:red}#BurnDown .total{fill:none;stroke:green}#BurnDown .planned{fill:none;stroke:gray}#BurnDown .earned{fill:none;stroke:orange}#BurnDown .total circle{fill:green}#BurnDown .planned circle{fill:gray}#BurnDown .earned circle{fill:orange}#BurnDownDetails>tbody>tr:hover{background-color:#f5f5f5;cursor:pointer}#BurnDownDetails>tbody>tr>td{padding:6px}#BurnDownDetails>tbody>tr>td.warning{font-weight:bold;color:#f00}#BurnDownDetails>tbody>tr>td.difference{font-size:1.3em;font-weight:bold;color:#00f;background-color:#e0ffff}#BurnDownDetails>tbody>tr>td.difference.warning{color:#f00;background-color:#ffccd5}#BurnDownDetails .user-info{margin:5px;padding:8px;font-weight:bold;background-color:#eee8aa}#BurnDownDetails .items{padding:5px 0 5px 20px}#BurnDownDetails .items a{color:#000;text-decoration:none}#BurnDownDetails .items a:hover{color:#00f;text-decoration:underline}#TimeSeries{width:100%;height:450px;background-color:#f5f5f5;border-radius:20px}#TimeSeries .surface{stroke:white}#TimeSeries .index{fill:black}#KambanBody .kamban-row{border-bottom:dotted 1px #c0c0c0}#KambanBody .kamban-container>div{min-height:30px}#KambanBody .kamban-container.hover{background-color:#f5f5f5}#KambanBody .kamban-container .kamban-item:last-child{margin:3px 3px 30px 3px}#KambanBody .kamban-item{margin:3px;padding:4px 16px 4px 5px;background-color:#fafad2;border:solid 1px #c0c0c0;position:relative;cursor:pointer;border-radius:5px}#KambanBody .kamban-item:hover{background-color:#fff;border:solid 1px #ffa500}#KambanBody .kamban-item.changed{font-weight:bold;background-color:#ff0;border:solid 1px #ffa500}#KambanBody .kamban-item .ui-icon{position:absolute;top:0;right:0}#ImageLib{float:left}#ImageLib .item{width:250px;height:250px;float:left;margin:10px 10px 0 0;padding:10px;border:solid 1px #c0c0c0;position:relative;overflow:hidden}#ImageLib .item .image{width:100%;float:left;margin:5px 0 0 0}#ImageLib .item .delete-image{float:left;position:absolute;right:5px;bottom:5px}#RecordHeader{width:100%;float:left;margin:0 0 5px 0}#RecordInfo{float:left;padding:6px 0 0 0}#RecordInfo div{float:left;margin-right:50px}#RecordInfo div p{float:left;margin-right:5px}#RecordInfo div p .elapsed-time{float:left;padding:0 5px;font-weight:bold;background-color:#eee;border-radius:2px}#RecordSwitchers{float:right}#RecordSwitchers>*{float:left}#RecordSwitchers .current{height:26px;display:block;float:left;margin:0 1px 0 0;padding:5px;border-radius:5px}#TemplateTabsContainer{width:100%;float:left}#Editor{width:100%;float:left;clear:both}#EditorTabsContainer{width:73%;float:left;margin:0 0 20px 0}#EditorTabsContainer.max{width:100%}#MailEditorTabsContainer{width:100%;float:left;margin:0 0 20px 0;border:none}#EditorComments{width:27%;float:right;margin:0 0 15px 0;padding:0 0 0 5px}#EditorComments .title-header{margin:3px 10px 8px 0}#CommentField{margin:0 0 5px 0}#OutgoingMailsForm{width:73%;float:left}#OutgoingMailsForm>.item{width:100%;float:left;position:relative;border-radius:10px}#OutgoingMailsForm .content{width:100%;float:left;margin:5px 0 20px 0;padding:10px 0 0 0;border:solid 1px #c0c0c0;border-top:none;border-radius:0 0 10px 10px/0 0 10px 10px}#DropDownSearchDialogForm{width:100%;padding:0 20px}#ProcessTabsContainer{margin:0 20px 10px 20px;clear:both}#StatusControlTabsContainer{margin:0 20px 10px 20px;clear:both}#StatusControlColumnHash .column-control-types{margin:0 0 0 10px}#ViewTabsContainer{margin:0 20px 10px 20px;clear:both}#ExportTabsContainer{margin:0 20px 10px 20px;clear:both}#EditorDetailTabsContainer{margin:0 20px 10px 20px;clear:both}#ColumnAccessControlTabsContainer{margin:0 20px 10px 20px;clear:both}#SearchResults{width:80%;float:left;margin:0 100px}#SearchResults .count{float:left;margin:0 0 10px 0}#SearchResults .count .label{height:26px;display:block;float:left;margin:0 5px 5px 0;padding:5px 10px;background:#dcdcdc;border-radius:5px}#SearchResults .count .data{height:26px;display:block;float:left;margin:0 5px 5px 0;padding:5px}#SearchResults .result{width:100%;float:left;padding:15px;border:solid 1px #fff;clear:both}#SearchResults .result>ul{display:block;float:left;clear:both}#SearchResults .result>h3{display:block;float:left;margin:5px 0;clear:both}#SearchResults .result>h3>a{font-size:1.3em;font-weight:bold}#SearchResults .result>p{display:block;float:left;clear:both}#SearchResults .result:hover{border:solid 1px #ffa500;cursor:pointer}#MainCommandsContainer{width:100%;height:47px;padding:7px 0 0 0;background-color:rgba(0,0,0,.65);position:fixed;left:0;bottom:30px;z-index:11}#MainCommands{text-align:center}#MainCommands>button{display:inline;float:none;margin:2px 4px}#ApiEditorCommands{padding:0 5px 200px 140px}#ApiEditorCommands>*{margin-right:10px}#BottomMargin{height:100px;clear:both}#Video{width:640px;height:480px;display:block;float:left;margin:0 16px}#Canvas{display:none}#Footer{width:100%;height:30px;display:block;padding:5px 10px;text-align:right;background-color:#000;position:fixed;left:0;bottom:0;z-index:10}#Footer a{color:#fff;text-decoration:none}#Versions{width:500px;margin:150px auto 20px auto;padding:50px;background-color:#f5f5f5;border-radius:10px}#Versions span{margin:10px;line-height:30px}.template{width:100%;display:block;float:left}.template-selectable{width:340px;display:block;float:left}.template-viewer-container{width:100%;display:block;float:right;margin:0 0 0 -340px}.template-viewer{margin:0 0 0 340px}.template-viewer .description{margin:10px 0 8px 0;padding:5px;background-color:#fefedd;border:solid 1px #c0c0c0;border-radius:5px}.template-viewer .samples-displayed{margin:0 0 8px 0;padding:5px;color:#f00;background-color:#ffc0cb;border:solid 1px #f00;border-radius:5px}.template-tab-container{min-height:600px}.main-form{clear:both}.nav-sites{margin:0 -10px;clear:both}.nav-site{width:220px;height:70px;float:left;margin:10px;position:relative;top:0;left:0;border-radius:5px}.nav-site .heading{width:50px;height:9px;position:absolute;top:-10px;left:5px;border-radius:3px 3px 0 0/3px 3px 0 0}.nav-site .stacking1{width:220px;height:70px;border-bottom:solid 1px #c0c0c0;border-right:solid 1px #c0c0c0;position:absolute;top:1px;left:1px;border-radius:5px}.nav-site .stacking2{width:220px;height:70px;border-bottom:solid 1px #c0c0c0;border-right:solid 1px #c0c0c0;position:absolute;top:4px;left:4px;border-radius:5px}.nav-site a{width:100%;height:100%;display:block;padding:10px 3px 3px 10px;overflow:hidden;word-wrap:break-word;text-decoration:none}.nav-site.has-image a{padding:10px 3px 3px 65px}.nav-site span.title{margin-left:5px}.nav-site.to-parent{height:36px;background-color:#fff}.nav-site.to-parent a{padding:9px 3px 3px 30px}.nav-site.to-parent.has-image a{padding:9px 3px 3px 35px}.nav-site.to-parent .ui-icon{position:absolute;top:9px;left:9px}.nav-site .site-image-thumbnail{position:absolute;top:8px;left:8px;border-radius:8px}.nav-site .site-image-icon{position:absolute;top:4px;left:8px;border-radius:8px}.nav-site .conditions{font-size:.75em;color:#000;position:absolute;right:1px;bottom:1px}.nav-site .conditions span{display:block;float:left;margin:2px 2px 2px 0;padding:2px 5px;background-color:#eee;border-radius:2px}.nav-site .conditions span.overdue{color:#fff;background-color:#f00}.nav-site .conditions span.elapsed-time.old{color:#c0c0c0}.error-page{padding:30px 50px;border-top:dotted 1px #808080}.error-page-title{margin:0 0 20px 0;padding:10px 0;font-weight:bold;color:#f00;border-bottom:dotted 1px #f00}.error-page-message{margin:15px 0 0 0;padding:5px 20px;font-weight:bold;color:#fff;background-color:#808080}.error-page-action{margin:5px 0 0 0;padding:5px 10px;color:#c0c0c0;background-color:#dcdcdc}.error-page-action em{margin:10px;color:#000}.error-page-stacktrace{margin:5px 0 0 0;padding:5px 20px;background-color:#f5f5f5}.fieldset.enclosed{margin:0 0 10px 0;padding:10px;border:solid 1px #c0c0c0;clear:both}.fieldset.enclosed-half{width:380px;float:left;margin:0 0 10px 0;padding:10px;border:solid 1px #c0c0c0}.fieldset.enclosed-thin{margin:0 0 10px 0;padding:5px 5px 5px 10px;border:solid 1px #c0c0c0;clear:both}.fieldset.enclosed-thin [class*="field-auto"]{height:35px}.fieldset.enclosed-auto{float:left;margin:0 0 10px 10px;padding:5px 5px 5px 10px;border:solid 1px #c0c0c0}.fieldset[class^="enclosed"]>legend{margin:0 0 0 10px;font-weight:bold}.command-field{padding:10px 5px 5px 136px;text-align:center;clear:both}.command-field>button{display:block;float:left;margin:2px 4px}.command-center{padding:5px 5px 5px 5px;text-align:center;clear:both}.command-center>button{display:inline;float:none;margin:2px 4px}.command-left{float:left;padding:5px 5px 5px 5px;clear:both}.command-left>*{display:block;float:left}.command-left>button{margin:2px 4px}.command-left>.ui-icon{margin:7px 3px 0 15px}.command-right{padding:5px 5px 5px 5px;text-align:right;clear:both}.command-right>button{display:inline;float:none;margin:2px 4px}.field-normal{width:340px;height:45px;float:left;padding:0 20px 10px 0}.field-normal>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-normal>.field-control{width:100%;float:right}:not(td)>div.field-normal .container-normal{width:auto;margin-left:120px}td>.field-normal,td>.field-wide{width:100%;padding:0}.field-normal>.buttons{padding:3px 10px}.field-normal .control-text{height:30px}.field-wide{width:100%;min-height:45px;float:left;padding:0 10px 10px 0;clear:both}.field-wide>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-wide>.field-control{width:100%;float:right}:not(td)>div.field-wide .container-normal{margin-left:120px}.field-markdown{width:100%;min-height:45px;float:left;padding:0 10px 10px 0;clear:both}.field-markdown>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-markdown>.field-control{width:100%;float:right}:not(td)>div.field-markdown .container-normal{margin-left:120px}.field-textarea{width:100%;min-height:45px;float:left;padding:0 10px 10px 0;clear:both}.field-textarea>.field-label{width:120px;float:left;margin-right:-120px;padding:7px 7px 7px 0;text-align:right}.field-textarea>.field-control{width:100%;float:right}:not(td)>div.field-textarea .container-normal{margin-left:120px}.field-auto{width:auto;height:45px;float:left;margin-right:35px;padding:0 10px 10px 0}.field-auto>.field-label{width:120px;float:left;padding:7px 7px 7px 0;text-align:right}.field-auto>.field-control{width:auto;float:left}.field-auto-thin{width:auto;height:45px;float:left;margin:0 5px;padding:0 10px 10px 0}.field-auto-thin>.field-label{float:left;padding:7px 7px 7px 0;text-align:right}.field-auto-thin>.field-control{width:auto;float:left}.field-auto-thin select{max-width:120px}.field-vertical{width:330px;height:100%;float:left;padding:0 20px 20px 0}.field-vertical>.field-label{width:100%;float:left;margin-right:-120px;padding:5px 10px;text-align:center}.field-vertical>.field-control{width:100%;float:left;clear:both}.field-label{overflow:hidden}label.required:after{margin-left:3px;color:#f00;content:'*'}.field-control .unit{display:block;float:left;padding:5px 0 0 5px}.field-section{width:100%;display:block;float:left;margin:15px;padding:2px 5px;font-weight:bold;border-bottom:solid 1px #c0c0c0;clear:both}.container-normal{position:relative}.container-left{width:340px;float:left;margin-right:-340px;padding:0 0 15px 0;position:relative}.container-right{width:100%;float:right;position:relative}.container-right>*{display:block;margin-left:340px}.control-text{width:100%;min-height:30px;display:block;padding:6px 4px 2px 4px;color:#000;background:#f5f5f5;border:solid 1px #c0c0c0;overflow:hidden;border-radius:5px}.control-textbox{width:100%;height:30px;padding:4px;border:solid 1px #c0c0c0;border-radius:5px}.control-textbox.with-unit{width:70%;display:block;float:left}.control-textbox.anchor{width:100%;height:30px;padding:4px;border:solid 1px #c0c0c0;border-radius:5px;z-index:0}.control-textarea{width:100%;height:100px;padding:4px 4px 4px 6px;border:solid 1px #c0c0c0;border-radius:5px}.control-attachments+label.error{height:22px;position:absolute;top:50px}.control-attachments-upload{width:100%;display:block;float:left;padding:25px 0;text-align:center;border:dotted 2px #d19405;border-radius:3px}.control-attachments-items{width:100%;display:block;float:left}.control-attachments-item{width:100%;display:block;float:left;margin:5px 0 0 0;padding:5px 10px;text-align:left;border:solid 1px #d19405;border-radius:5px}.progress-bar{width:100%;height:30px;display:block;float:left;margin:5px 0 0 0;vertical-align:top;border:solid 1px #d19405;overflow:hidden;border-radius:5px}.progress-bar>div{width:0;height:100%;line-height:22px;color:#fff;background-color:#fece2f;border-radius:3px}.already-attachments{background-color:#fece2f}.preparation-delete{background-color:#f5f5f5;border:solid 1px #c0c0c0}.preparation-delete>a{color:#c0c0c0}.show-file{display:block;float:left;margin:0}.file-name{display:block;float:left}.delete-file{display:block;float:right;margin:2px -5px 0 0}.field-control .control-markup{width:100%;min-height:100px;float:left;padding:4px 25px 4px 6px;color:#000;background:#f5f5f5;border:solid 1px #c0c0c0;border-radius:5px}.md{width:100%;float:left;line-height:1.5em;font-family:Terminal;word-wrap:break-word;word-break:break-all}.md>*{float:left;clear:both}.md h1{margin:10px 0 10px 0;font-weight:bold}.md h1:not(:first-child){margin:20px 0 10px 0}.md h2{margin:5px 0 8px 0;font-weight:bold}.md h2:not(:first-child){margin:20px 0 8px 0}.md h3{margin:3px 0 6px 0;font-weight:bold}.md h3:not(:first-child){margin:10px 0 6px 0}.md h4{margin:3px 0 4px 0;font-weight:bold}.md h4:not(:first-child){margin:10px 0 4px 0}.md h5{margin:3px 0 2px 0;font-weight:bold}.md h5:not(:first-child){margin:10px 0 2px 0}.md h6{margin:3px 0 2px 0;font-weight:bold}.md h6:not(:first-child){margin:10px 0 2px 0}.md hr{float:none;clear:both}.md ol{margin:0 10px 10px 32px;list-style-type:decimal}.md p{margin:0 0 10px 0;clear:both}.md table{width:auto;margin:0 0 10px 0;background-color:#fff}.md td{padding:5px 10px;border:solid 1px #c0c0c0}.md th{padding:5px 10px;font-weight:bold;border:solid 1px #c0c0c0}.md tbody tr:nth-child(odd){background-color:#f5f5f5}.md ul{margin:0 10px 10px 32px;list-style-type:disc}.control-markdown{width:100%;display:none;padding:4px 4px 4px 6px;border:solid 1px #c0c0c0;border-radius:5px}.control-dropdown{width:100%;height:30px;padding:4px;border:solid 1px #c0c0c0;border-radius:5px}.control-spinner{width:auto;height:22px;display:block;float:left;padding:1px;color:#000}.control-checkbox{display:block;float:left;margin:8px 0}.control-checkbox~label{display:block;float:left;margin:7px 5px 0 7px}.control-checkbox+.ui-icon.ui-icon-info{display:block;float:left;margin:7px -7px 0 0}.field-normal .control-checkbox+label{width:175px}_::-webkit-full-page-media,_:future,:root .field-normal .control-checkbox+label{width:172px}.control-radio{display:block;float:left;margin:8px 0}.control-radio+label{display:block;float:left;margin:4px 10px 5px 7px}.control-slider{width:30px;float:left;margin:8px 0 0 12px}.control-slider-ui{width:140px;float:left;margin:11px 0 0 5px}.container-selectable .wrapper{width:100%;min-height:300px;display:block;float:left;background-color:#f5f5f5;border:solid 1px #c0c0c0;overflow:auto;border-radius:5px}.control-selectable{width:100%;display:block;float:left;padding:5px 10px 5px 5px;list-style-type:none;touch-action:pan-y}.control-selectable li{width:100%;min-height:24px;margin:3px;padding:2px 5px;border-radius:5px}.control-basket{margin-left:120px;padding:5px 5px 0 5px;background-color:#f5f5f5;border:solid 1px #c0c0c0;border-radius:5px}.control-basket>li{display:block;float:left;margin:0 5px 5px 0;padding:3px 5px;border-radius:5px}.control-basket>li>span{display:block;float:left;z-index:2}.comment{width:100%;display:block;float:left;margin:0 0 5px 0;padding:5px 10px 10px 20px;background:#fafad2;border:solid 1px #c0c0c0;position:relative;clear:both}.comment>*{display:block;float:left}.comment>.time{float:left;margin:0 0 8px -10px;margin-right:10px}.comment>.body{width:100%;clear:both}.comment>.button.edit{position:absolute;top:3px;right:20px;cursor:pointer}.comment>.button.delete{position:absolute;top:3px;right:5px;cursor:pointer}.comment>.control-markup{width:100%}.comment>.control-markdown{width:100%;display:none}.user{float:left}.user>span{display:block;float:left;font-weight:bold}.dept{float:left}.dept>span{display:block;float:left;font-weight:bold}.both{clear:both}.hidden{display:none}.right{float:right}.right-align{text-align:right;text-align-last:right}.tooltip{display:none;position:absolute}.no-border{border:none}.grid{margin:0 0 10px 0}.grid.fixed{table-layout:fixed}.grid>thead>tr>caption{margin:0 0 5px 0}.grid>thead>tr>th{padding:6px;vertical-align:middle;border-top:solid 1px transparent;border-bottom:solid 1px transparent;border-left:solid 1px transparent;border-right:solid 1px #fff;word-wrap:break-word}.grid>thead>tr>th>div{width:100%;float:left;text-align:center;z-index:2}.grid>thead>tr>th span{display:block;float:left}.grid>thead>tr:first-child>th:first-child{border-radius:10px 0 0 0/10px 0 0 0}.grid>thead>tr:first-child>th:last-child{border-right:solid 1px transparent;border-radius:0 10px 0 0/0 10px 0 0}.grid>thead>tr>th.sortable:hover{cursor:pointer}.grid>tbody>tr>td{max-width:300px;border-left:dotted 1px #c0c0c0;border-right:dotted 1px #c0c0c0;word-wrap:break-word}.grid>tbody>tr.message-row>td{padding:0;text-align:center}.grid>tbody>tr [class*="status-"]{padding:0 5px;font-weight:bold;border:solid 1px #c0c0c0;border-radius:3px}.grid>tbody>tr>th{padding:6px;vertical-align:middle;font-weight:normal;background-color:#dcdcdc;border-top:solid 1px #fff;border-bottom:solid 1px #fff;border-left:solid 1px transparent;border-right:solid 1px transparent;word-wrap:break-word}.grid-row{background-color:#fff;border-bottom:solid 1px #c0c0c0}.grid-row td{overflow:hidden}.grid-row .comment{min-width:200px;max-height:100px;margin:0 0 3px 0;padding:3px 6px 3px 15px;background:#fafad2;border:solid 1px #fff;clear:both;overflow:hidden}.grid-row .comment.one-third{max-height:306px}.grid-row .comment.half{max-height:151px}.grid:not(.not-link) .grid-row:hover{background-color:#f5f5f5;cursor:pointer}.grid-row:hover .comment{background-color:#ffffe0}.grid-row p{float:left}.grid-row p.body{clear:both}.grid-row[data-history]{background-color:#d3d3d3}.grid-title-body{min-width:200px;max-height:306px;margin:0 0 3px 0;padding:3px 6px;background:inherit;border:solid 1px transparent;clear:both;overflow:hidden}.grid-title-body>.body{width:100%}.grid-title-body>.title+.body{padding:8px 0 0 10px}.links{padding:0 10px}.link-creations button{display:block;float:left;margin:0 10px 0 0}.text{width:250px;display:block;float:left;border:solid 1px #c0c0c0}.datepicker{display:block;float:left;border:solid 1px #c0c0c0}.dropdown{display:block;float:left;border:solid 1px #c0c0c0}[class*="limit-"]{margin-left:10px;padding:0 5px}.limit-warning1{color:#f00}.limit-warning2{color:#f00;background-color:#ffccd5}.limit-warning3{color:#fff;background-color:#f00}.message{width:100%;text-align:center;position:fixed;left:0;bottom:78px;z-index:100}.message .body{margin-bottom:4px;position:relative;border-radius:20px}.message .close{background-color:#fff;position:absolute;top:11px;right:8px;cursor:pointer;border-radius:10px}.message-dialog{width:100%;display:block;float:left;margin:0 auto;text-align:center}.message-form-bottom{width:600px;margin:0 auto;text-align:center}.alert-error{min-height:32px;display:block;padding:5px;color:#fff;background-color:rgba(255,0,0,.9);border:solid 1px #f00}.alert-success{min-height:32px;display:block;padding:5px;color:#fff;background-color:rgba(0,128,0,.9);border:solid 1px #008000}.alert-warning{min-height:32px;display:block;padding:5px;color:#000;background-color:#ff0;border:solid 1px #ff0}.alert-information{min-height:32px;display:block;padding:5px;color:#fff;background-color:#00f;border:solid 1px #00f}label.error{width:100%;display:block;float:left;padding:0 5px;color:#f00;background-color:#fff;border-top:none;top:-5px;left:0;border-radius:0 0 5px 5px/0 0 5px 5px;z-index:2}.ui-spinner>label.error{margin-top:3px}.error{border:solid 1px #f00}.error+.ui-widget.ui-state-default.ui-multiselect{border:solid 1px #f00}.with-unit+label.error{width:70%;position:absolute;top:25px}.button-edit-markdown{position:absolute;top:5px;right:5px;cursor:pointer;z-index:1}.comment>.button-edit-markdown{top:6px;right:20px}.button-delete-address{cursor:pointer}.button-right-justified{float:right}.status-new{background:#fff}.status-preparation{color:#fff;background:#ff8c00}.status-inprogress{color:#fff;background:#008000}.status-review{background:#ff0}.status-closed{color:#fff;background:#00f}.status-rejected{color:#fff;background:#808080}.always-hidden{display:none}h3.title-header{height:40px;padding:10px 20px;text-align:center;background-color:#dcdcdc;border:solid 1px #a9a9a9;border-radius:10px 10px 0 0/10px 10px 0 0}.outgoing-mail .dialog{padding:0 !important}.outgoing-mail .ui-dialog-titlebar{display:none}.svg-work-value{width:50px;height:40px}.svg-work-value rect:nth-of-type(1){fill:gainsboro}.svg-work-value rect:nth-of-type(2){fill:darkseagreen}.svg-progress-rate{width:50px;height:40px}.svg-progress-rate.warning text{fill:red}.svg-progress-rate rect:nth-of-type(1){fill:gainsboro}.svg-progress-rate rect:nth-of-type(2){fill:gray}.svg-progress-rate rect:nth-of-type(3){fill:darkseagreen}.svg-progress-rate.warning rect:nth-of-type(3){fill:#ffccd5}.svg-kamban-aggregation-view{width:100%;height:20px}.svg-kamban-aggregation-view rect{height:20px;fill:darkseagreen}.svg-crosstab{width:100%;height:20px}.svg-crosstab rect{height:20px;fill:darkseagreen}.axis{fill:none;stroke:gray;shape-rendering:crispEdges}.h2{margin:0 0 5px 0;padding:0}.h3{margin:0 0 5px 10px;padding:0}.h4{margin:0 0 5px 20px;padding:0}.h5{margin:0 0 5px 30px;padding:0}.h6{margin:0 0 5px 40px;padding:0}.h2>h2{padding:5px 0;font-weight:bold;border-bottom:solid 1px #c0c0c0}.h3>h3{font-weight:bold}.h4>h4{font-weight:bold}.h5>h5{font-weight:bold}.h6>h6{font-weight:bold}.w50{width:50px}.w100{width:100px}.w150{width:150px}.w200{width:200px}.w250{width:250px}.w300{width:300px}.w350{width:350px}.w400{width:400px}.w450{width:450px}.w500{width:500px}.w550{width:550px}.w600{width:600px}.h100{height:100px}.h150{height:150px}.h200{height:200px}.h250{height:250px}.h300{height:300px}.h350{height:350px}.h400{height:400px}.h450{height:450px}.h500{height:500px}.h550{height:550px}.h600{height:600px}.m-l10{margin-left:10px}.m-l20{margin-left:20px}.m-l30{margin-left:30px}.m-l40{margin-left:40px}.m-l50{margin-left:50px}.paragraph{padding:3px 3px 3px 10px}.dialog{display:none;padding:15px 0 10px 0 !important}.dialog .fieldset{margin:0 10px 10px 10px}.link span{margin-right:5px}.link span.bold{font-weight:bold;cursor:pointer}.histories-form{padding:20px}.ui-widget input,.ui-widget select,.ui-widget button{font-family:Hiragino Kaku Gothic Pro,"Meiryo UI",sans-serif}.ui-widget textarea{line-height:1.5em;font-family:Terminal}.ui-widget{font-size:1em}.ui-button{padding:4px 4px 4px 2px !important}.ui-dialog{overflow:visible !important}.ui-icon.a{float:left;margin:6px 0 0 0}.ui-spinner{display:block;float:left;background:#fff;max-height:46px}.ui-widget.ui-state-default.ui-multiselect{height:30px;background:#fff;border:solid 1px #c0c0c0;overflow:hidden;border-radius:5px}.ui-multiselect-checkboxes{min-height:300px}.ui-multiselect-checkboxes input{margin:0 5px}.ui-corner-all.ui-state-hover{border-radius:2px}div.field-control .ui-multiselect.ui-state-disabled{background-color:#f5f5f5;opacity:1}.height-auto{max-height:none !important}.focus-inform{background-color:#fff !important;border:solid 1px #ffa500 !important}.menu-negative{border-left:solid 1px #fff;border-right:solid 1px #fff;position:absolute;z-index:10}.menu-negative>li{width:100%;display:block;float:left;border-top:dotted 1px #fff;cursor:pointer;clear:both}.menu-sort{border-left:solid 1px #fff;border-right:solid 1px #fff;position:absolute;border-radius:0 0 10px 10px/0 0 10px 10px;z-index:10}.menu-sort>li{width:100%;display:block;float:left;border-top:dotted 1px #fff;cursor:pointer;clear:both}.menu-sort>li.ui-menu-divider{height:initial;font-size:initial}.menu-sort>li.grid-header-filter .ui-icon{position:initial}.menu-sort>li:not(.grid-header-filter) div.field-control>*{border:solid 1px #c0c0c0}.current-time{position:absolute;top:9px;right:-17px;cursor:pointer;z-index:10}.current-user{position:absolute;top:9px;right:-17px;cursor:pointer;z-index:10}.current-dept{position:absolute;top:9px;right:-17px;cursor:pointer;z-index:10}input:focus{background-color:#ffc}select:focus:not(.has-css){background-color:#ffc}textarea:focus{background-color:#ffc}.ssoLoginMessage{margin:10px;padding:6px;border-top:solid 1px #c0c0c0}#EnterPriseBanner{width:238px;position:fixed;right:8px;bottom:280px;z-index:3}#SupportBanner{width:238px;position:fixed;right:8px;bottom:180px;z-index:3}#CasesBanner{width:238px;position:fixed;right:8px;bottom:80px;z-index:3} \ No newline at end of file diff --git a/Implem.Pleasanter/wwwroot/scripts/_form.js b/Implem.Pleasanter/wwwroot/scripts/_form.js index 031c25cbf..875bac4bf 100644 --- a/Implem.Pleasanter/wwwroot/scripts/_form.js +++ b/Implem.Pleasanter/wwwroot/scripts/_form.js @@ -73,7 +73,6 @@ $p.send = function ($control, formId, _async, clearMessage) { _async = _async !== undefined ? _async : true; if (methodType !== 'get') { data.ControlId = $control.attr('id'); - $p.setMustData($form, action); } if ($control.hasClass('validate')) { if ($p.before_validate($p.eventArgs(url, methodType, data, $control, _async)) === false) { @@ -94,6 +93,9 @@ $p.send = function ($control, formId, _async, clearMessage) { return false; } } + if (methodType !== 'get') { + $p.setMustData($form, action); + } if (methodType !== undefined) { return $p.ajax( url, diff --git a/Implem.Pleasanter/wwwroot/styles/site.css b/Implem.Pleasanter/wwwroot/styles/site.css index 636a68c26..9164b7b23 100644 --- a/Implem.Pleasanter/wwwroot/styles/site.css +++ b/Implem.Pleasanter/wwwroot/styles/site.css @@ -181,9 +181,10 @@ pre{ } #PortalLink{ - position:fixed; - top:10px; + position:relative; + top:-38px; right:40px; + float:right; } #LoginFieldSet{ @@ -255,7 +256,6 @@ pre{ #Header{ width:100%; - height:42px; float:left; padding:0px 6px; border:none; @@ -265,13 +265,13 @@ pre{ #Navigations{ height:30px; - margin:5px 0px; + margin:0px 0px 5px 0px; padding:0px 5px 0px 15px; border:none; - position:absolute; top:0px; right:5px; border-radius:20px 5px 5px 20px; + float:right; } #NavigationMenu{ @@ -1852,7 +1852,7 @@ td > .field-normal,td > .field-wide{ overflow:hidden; } -.field-label .required:after{ +label.required:after{ margin-left:3px; color:red; content:'*'; diff --git a/Implem.TestAutomation/implem.TestAutomation.csproj b/Implem.TestAutomation/implem.TestAutomation.csproj index e4efc14a9..e6d02376a 100644 --- a/Implem.TestAutomation/implem.TestAutomation.csproj +++ b/Implem.TestAutomation/implem.TestAutomation.csproj @@ -4,9 +4,9 @@ Exe net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 Linux diff --git a/Rds/Implem.IRds/ISqls.cs b/Rds/Implem.IRds/ISqls.cs index b7df47459..bc386dcaa 100644 --- a/Rds/Implem.IRds/ISqls.cs +++ b/Rds/Implem.IRds/ISqls.cs @@ -21,6 +21,7 @@ public interface ISqls object DateTimeValue(object value); string BooleanString(string value); string IntegerColumnLike(string tableName, string columnName); + string DateAddDay(int day, string columnBracket); string DateAddHour(int hour, string columnBracket); string DateGroupYearly { get; } string DateGroupMonthly { get; } diff --git a/Rds/Implem.IRds/Implem.IRds.csproj b/Rds/Implem.IRds/Implem.IRds.csproj index ec6b8924f..9df5c5b7f 100644 --- a/Rds/Implem.IRds/Implem.IRds.csproj +++ b/Rds/Implem.IRds/Implem.IRds.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj b/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj index bd92806e3..911f16192 100644 --- a/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj +++ b/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Rds/Implem.PostgreSql/PostgreSqlSqls.cs b/Rds/Implem.PostgreSql/PostgreSqlSqls.cs index 6b2709a39..f017cb930 100644 --- a/Rds/Implem.PostgreSql/PostgreSqlSqls.cs +++ b/Rds/Implem.PostgreSql/PostgreSqlSqls.cs @@ -60,6 +60,11 @@ public string IntegerColumnLike(string tableName, string columnName) return "(cast(\"" + tableName + "\".\"" + columnName + "\" as text) like "; } + public string DateAddDay(int day, string columnBracket) + { + return $"\"{columnBracket}\" + cast('{day} days' as interval)"; + } + public string DateAddHour(int hour, string columnBracket) { return $"{columnBracket} + interval '{hour} hour'"; diff --git a/Rds/Implem.SqlServer/Implem.SqlServer.csproj b/Rds/Implem.SqlServer/Implem.SqlServer.csproj index 40d8f93bf..87d21865d 100644 --- a/Rds/Implem.SqlServer/Implem.SqlServer.csproj +++ b/Rds/Implem.SqlServer/Implem.SqlServer.csproj @@ -3,9 +3,9 @@ net6.0 Copyright © Implem Inc 2014 - 2022 - 1.3.25.3 - 1.3.25.3 - 1.3.25.3 + 1.3.26.0 + 1.3.26.0 + 1.3.26.0 disable diff --git a/Rds/Implem.SqlServer/SqlServerSqls.cs b/Rds/Implem.SqlServer/SqlServerSqls.cs index ac3a59524..3b6d03274 100644 --- a/Rds/Implem.SqlServer/SqlServerSqls.cs +++ b/Rds/Implem.SqlServer/SqlServerSqls.cs @@ -56,6 +56,11 @@ public string IntegerColumnLike(string tableName, string columnName) return "(\"" + tableName + "\".\"" + columnName + "\" like "; } + public string DateAddDay(int day, string columnBracket) + { + return $"dateadd(day, {day}, {columnBracket})"; + } + public string DateAddHour(int hour, string columnBracket) { return $"dateadd(hour,{hour},{columnBracket})";