diff --git a/Implem.CodeDefiner/Dockerfile b/Implem.CodeDefiner/Dockerfile index 67f806104..2c55e968a 100644 --- a/Implem.CodeDefiner/Dockerfile +++ b/Implem.CodeDefiner/Dockerfile @@ -1,7 +1,7 @@ #See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. -FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base -FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build +FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["Implem.CodeDefiner/Implem.CodeDefiner.csproj", "Implem.CodeDefiner/"] COPY ["Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj", "Implem.DefinitionAccessor/"] @@ -19,7 +19,10 @@ RUN dotnet build "Implem.CodeDefiner/Implem.CodeDefiner.csproj" -c Release -o /a RUN dotnet build "Implem.Pleasanter/Implem.Pleasanter.csproj" -c Release -o /app/build/Implem.Pleasanter FROM build AS publish -RUN apt-get update && apt-get install -y jq +RUN apt-get update && apt-get install -y jq \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + RUN dotnet publish "Implem.CodeDefiner/Implem.CodeDefiner.csproj" -c Release -o /app/publish/Implem.CodeDefiner RUN dotnet publish "Implem.Pleasanter/Implem.Pleasanter.csproj" -c Release -o /app/publish/Implem.Pleasanter RUN cat Implem.Pleasanter/App_Data/Parameters/Rds.json \ diff --git a/Implem.CodeDefiner/Implem.CodeDefiner.csproj b/Implem.CodeDefiner/Implem.CodeDefiner.csproj index ed2b4c655..479e213df 100644 --- a/Implem.CodeDefiner/Implem.CodeDefiner.csproj +++ b/Implem.CodeDefiner/Implem.CodeDefiner.csproj @@ -2,12 +2,12 @@ Exe - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 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.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 Linux diff --git a/Implem.DefinitionAccessor/Def.cs b/Implem.DefinitionAccessor/Def.cs index acad93781..29c44fe58 100644 --- a/Implem.DefinitionAccessor/Def.cs +++ b/Implem.DefinitionAccessor/Def.cs @@ -1044,6 +1044,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_GetModels_SysLogs_UseFilterButton": Code.SiteSettings_GetModels_SysLogs_UseFilterButton = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.SiteSettings_GetModels_SysLogs_UseFilterButton, definitionRow, CodeXls); break; case "SiteSettings_GetModels_Users": Code.SiteSettings_GetModels_Users = definitionRow[1].ToString().NoSpace(definitionRow["NoSpace"].ToBool()); SetCodeTable(CodeTable.SiteSettings_GetModels_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; @@ -7499,6 +7500,7 @@ public class CodeColumn2nd public string SiteSettings_GetModels_Items; public string SiteSettings_GetModels_Items_Choices; public string SiteSettings_GetModels_Items_SiteIntegration; + public string SiteSettings_GetModels_SysLogs_UseFilterButton; public string SiteSettings_GetModels_Users; public string Summaries; public string Summaries_DataTablesCases; @@ -8304,6 +8306,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_GetModels_SysLogs_UseFilterButton = new CodeDefinition(); public CodeDefinition SiteSettings_GetModels_Users = new CodeDefinition(); public CodeDefinition Summaries = new CodeDefinition(); public CodeDefinition Summaries_DataTablesCases = new CodeDefinition(); diff --git a/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj b/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj index 698764bb4..6ee6a4ea5 100644 --- a/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj +++ b/Implem.DefinitionAccessor/Implem.DefinitionAccessor.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable diff --git a/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj b/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj index 8b9acd14b..90fd28b5a 100644 --- a/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj +++ b/Implem.DisplayAccessor/Implem.DisplayAccessor.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable diff --git a/Implem.Factory/Implem.Factory.csproj b/Implem.Factory/Implem.Factory.csproj index 267a60959..bab14066e 100644 --- a/Implem.Factory/Implem.Factory.csproj +++ b/Implem.Factory/Implem.Factory.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable diff --git a/Implem.Libraries/Classes/XlsIo.cs b/Implem.Libraries/Classes/XlsIo.cs index c6699b1fa..ee07821c2 100644 --- a/Implem.Libraries/Classes/XlsIo.cs +++ b/Implem.Libraries/Classes/XlsIo.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Wordprocessing; -using Implem.Libraries.Utilities; +using Implem.Libraries.Utilities; using System; using System.Collections.Generic; using System.IO; @@ -125,20 +124,6 @@ public XlsRow(Dictionary data) data.ForEach(o => Add(o.Key, o.Value)); } - protected XlsRow( - SerializationInfo serializationInfo, - StreamingContext streamingContext) - : base(serializationInfo, streamingContext) - { - } - - public override void GetObjectData( - SerializationInfo serializationInfo, - StreamingContext streamingContext) - { - base.GetObjectData(serializationInfo, streamingContext); - } - public string this[int index] { get diff --git a/Implem.Libraries/Implem.Libraries.csproj b/Implem.Libraries/Implem.Libraries.csproj index 0b1828391..65d65febd 100644 --- a/Implem.Libraries/Implem.Libraries.csproj +++ b/Implem.Libraries/Implem.Libraries.csproj @@ -1,19 +1,18 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable - - + diff --git a/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj b/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj index 479b2c3e4..e28c14d02 100644 --- a/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj +++ b/Implem.ParameterAccessor/Implem.ParameterAccessor.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByFormula_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByFormula_Body.txt index 56852e0e8..d98f537b3 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByFormula_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_SetByFormula_Body.txt @@ -67,40 +67,45 @@ ss: ss, formulaScript: formulaSet.FormulaScript, calculationMethod: formulaSet.CalculationMethod); - try + var value = FormulaServerScriptUtilities.Execute( + context: context, + ss: ss, + itemModel: this, + formulaScript: formulaSet.FormulaScript); + switch (value) { - var value = FormulaServerScriptUtilities.Execute( - context: context, - ss: ss, - itemModel: this, - formulaScript: formulaSet.FormulaScript); - var formData = new Dictionary - { - { $"#TableName#_{columnName}", value.ToString() } - }; - SetByFormData( - context: context, - ss: ss, - formData: formData); - if (ss.OutputFormulaLogs == true) - { - context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); - context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); - context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); - } + case "#N/A": + case "#VALUE!": + case "#REF!": + case "#DIV/0!": + case "#NUM!": + case "#NAME?": + case "#NULL!": + case "Invalid Parameter": + if (formulaSet.IsDisplayError == true) + { + throw new Exception($"Formula error {value}"); + } + new SysLogModel( + context: context, + method: nameof(SetByFormula), + message: $"Formula error {value}", + sysLogType: SysLogModel.SysLogTypes.Execption); + break; } - catch (Exception exception) + var formData = new Dictionary { - if (formulaSet.IsDisplayError == true) - { - throw new Exception($"Formula error {exception.Message}"); - } - new SysLogModel( - context: context, - method: nameof(SetByFormula), - message: $"Formula error {exception.Message}", - errStackTrace: exception.StackTrace, - sysLogType: SysLogModel.SysLogTypes.Execption); + { $"#TableName#_{columnName}", value.ToString() } + }; + SetByFormData( + context: context, + ss: ss, + formData: formData); + if (ss.OutputFormulaLogs == true) + { + context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); + context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); + context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); } } }); diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateByKambanCases.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateByKambanCases.json index 763cf4c74..c84cf17c3 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateByKambanCases.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_UpdateByKambanCases.json @@ -4,5 +4,5 @@ "Indent": "4", "Separator": "\\r\\n", "ItemOnly": "1", - "Exclude": "Sites,Wikis,Dashboards" + "Exclude": "Sites,Wikis" } \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_Kamban_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_Kamban_Body.txt index f8e76d423..baaab9ca8 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_Kamban_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Model_Utilities_Kamban_Body.txt @@ -27,19 +27,31 @@ var serverScriptModelRow = ss.GetServerScriptModelRow( context: context, view: view); - return hb.ViewModeTemplate( - context: context, - ss: ss, - view: view, - viewMode: viewMode, - serverScriptModelRow: serverScriptModelRow, - viewModeBody: () => hb - .Kamban( - context: context, - ss: ss, - view: view, - bodyOnly: false, - inRange: inRange)); + if (ss.DashboardParts?.Any() != true) + { + return hb.ViewModeTemplate( + context: context, + ss: ss, + view: view, + viewMode: viewMode, + serverScriptModelRow: serverScriptModelRow, + viewModeBody: () => hb + .Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: false, + inRange: inRange)); + } + else + { + return hb.Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: false, + inRange: inRange).ToString(); + } } public static string KambanJson( @@ -52,59 +64,79 @@ public static string KambanJson( return Messages.ResponseHasNotPermission(context: context).ToJson(); } var view = Views.GetBySession(context: context, ss: ss); - var bodyOnly = context.Forms.ControlId().StartsWith("Kamban"); + var bodyOnly = ss.DashboardParts?.Any() == true + ? false + : context.Forms.ControlId().StartsWith("Kamban"); var res = new ResponseCollection(context: context); + var suffix = view.GetKambanSuffix(); if (context.ErrorData.Type != Error.Types.None) { res.Message(context.ErrorData.Message(context: context)); } - if (InRange( - context: context, - ss: ss, - view: view, - limit: Parameters.General.KambanLimit)) + if (ss.DashboardParts?.Any() != true) { - var body = new HtmlBuilder().Kamban( + if (InRange( context: context, ss: ss, view: view, - bodyOnly: bodyOnly, - changedItemId: updated - ? context.Forms.Long("KambanId") - : 0); - return res - .ViewMode( + limit: Parameters.General.KambanLimit)) + { + var body = new HtmlBuilder().Kamban( context: context, ss: ss, view: view, - invoke: "setKamban", bodyOnly: bodyOnly, - bodySelector: "#KambanBody", - body: body) - .Events("on_kamban_load") - .ToJson(); + changedItemId: updated + ? context.Forms.Long("KambanId") + : 0); + return res + .ViewMode( + context: context, + ss: ss, + view: view, + invoke: "setKamban", + bodyOnly: bodyOnly, + bodySelector: $"#KambanBody{suffix}", + body: body, + replaceAllBody: true) + .Events("on_kamban_load") + .ToJson(); + } + else + { + var body = new HtmlBuilder().Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: bodyOnly, + inRange: false); + return res + .ViewMode( + context: context, + ss: ss, + view: view, + message: Messages.TooManyCases( + context: context, + data: Parameters.General.KambanLimit.ToString()), + bodyOnly: bodyOnly, + bodySelector: $"#KambanBody{suffix}", + body: body, + replaceAllBody: true) + .Events("on_kamban_load") + .ToJson(); + } } else { var body = new HtmlBuilder().Kamban( - context: context, - ss: ss, - view: view, - bodyOnly: bodyOnly, - inRange: false); - return res - .ViewMode( context: context, ss: ss, view: view, - message: Messages.TooManyCases( - context: context, - data: Parameters.General.KambanLimit.ToString()), bodyOnly: bodyOnly, - bodySelector: "#KambanBody", - body: body) - .Events("on_kamban_load") - .ToJson(); + changedItemId: updated + ? context.Forms.Long("KambanId") + : 0); + return body.ToString(); } } @@ -149,6 +181,7 @@ private static HtmlBuilder Kamban( groupByX: groupByX, groupByY: groupByY, value: value); + var suffix = view.GetKambanSuffix(); return !bodyOnly ? hb.Kamban( context: context, @@ -162,7 +195,9 @@ private static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, - inRange: inRange) + inRange: inRange, + suffix: suffix, + changedItemId: changedItemId) : hb.KambanBody( context: context, ss: ss, @@ -175,6 +210,7 @@ private static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, + suffix: suffix, changedItemId: changedItemId, inRange: inRange); } @@ -189,6 +225,7 @@ private static IEnumerable KambanData( { var column = Rds.#TableName#Column() .#ModelName#Id() + .SiteId() .Status() .ItemTitle(ss.ReferenceType) .Add( @@ -200,9 +237,13 @@ private static IEnumerable KambanData( .Add( context: context, column: value); - var where = view.Where( + var where = ss.DashboardParts?.Any() == true + ? ss.DashboardParts[0].View.Where(context: context, ss: ss) + : new SqlWhereCollection(); + where = view.Where( context: context, - ss: ss); + ss: ss, + where: where); var param = view.Param( context: context, ss: ss); @@ -223,6 +264,7 @@ private static IEnumerable KambanData( .Select(o => new Libraries.ViewModes.KambanElement() { Id = o.Long("#ModelName#Id"), + SiteId = o.Long("SiteId"), Title = o.String("ItemTitle"), Status = new Status(o.Int("Status")), GroupX = groupByX?.ConvertIfUserColumn(o), diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Rds_Columns_ConstSqlWhereLike_Numeric_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Rds_Columns_ConstSqlWhereLike_Numeric_Body.txt index 7d8f443c0..35acc3c2a 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Rds_Columns_ConstSqlWhereLike_Numeric_Body.txt +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/Rds_Columns_ConstSqlWhereLike_Numeric_Body.txt @@ -4,9 +4,9 @@ string name = "SearchText", bool forward = false) { - return factory.Sqls.IntegerColumnLike(tableName, "#ColumnName#") + - (forward + return factory.Sqls.IntegerColumnLike(tableName, "#ColumnName#") + + (forward ? string.Empty - : factory.Sqls.WhereLikeTemplateForward) + - $"@{name}{factory.Sqls.WhereLikeTemplate})"; + : factory.Sqls.WhereLikeTemplateForward) + + $"@{name}{factory.Sqls.WhereLikeTemplate})"; } \ No newline at end of file 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 db37a590b..9f5f37841 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); + ss.TableType = tableTypes; return ss; diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_SysLogs_UseFilterButton.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_SysLogs_UseFilterButton.json new file mode 100644 index 000000000..f21c7ac99 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_SysLogs_UseFilterButton.json @@ -0,0 +1,6 @@ +{ + "Id": "SiteSettings_GetModels_SysLogs_UseFilterButton", + "Indent": "3", + "GenericUi": "1", + "Include": "SysLogs" +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_SysLogs_UseFilterButton_Body.txt b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_SysLogs_UseFilterButton_Body.txt new file mode 100644 index 000000000..2ca698b6d --- /dev/null +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Code/SiteSettings_GetModels_SysLogs_UseFilterButton_Body.txt @@ -0,0 +1,2 @@ +ss.UseFilterButton = true; +ss.AlwaysRequestSearchCondition = true; \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Sites_SiteId.json b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Sites_SiteId.json index 0ab823ae0..5feb8b124 100644 --- a/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Sites_SiteId.json +++ b/Implem.Pleasanter/App_Data/Definitions/Definition_Column/Sites_SiteId.json @@ -21,6 +21,7 @@ "Required": "1", "SearchIndexPriority": "1", "ItemId": "10", + "Like": "1", "ControlCss": " not-send", "ControlType": "Id", "EditorReadOnly": "1", diff --git a/Implem.Pleasanter/App_Data/Displays/CannotMoveMultipleSitesData.json b/Implem.Pleasanter/App_Data/Displays/CannotMoveMultipleSitesData.json new file mode 100644 index 000000000..64e2e68d2 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Displays/CannotMoveMultipleSitesData.json @@ -0,0 +1,33 @@ +{ + "Id": "CannotMoveMultipleSitesData", + "Type": 240, + "Languages": [ + { + "Body": "Unable to navigate as it is displaying records from multiple sites." + }, + { + "Language": "zh", + "Body": "由于显示了多个站点的记录,因此无法导航。" + }, + { + "Language": "ja", + "Body": "複数のサイトのレコードを表示しているため、移動できません。" + }, + { + "Language": "de", + "Body": "Aufgrund der Anzeige von Datensätzen von mehreren Websites kann nicht navigiert werden." + }, + { + "Language": "ko", + "Body": "여러 사이트의 레코드를 표시하고 있어 이동할 수 없습니다." + }, + { + "Language": "es", + "Body": "No se puede navegar ya que muestra registros de varios sitios." + }, + { + "Language": "vn", + "Body": "Không thể di chuyển vì đang hiển thị bản ghi từ nhiều trang web." + } + ] +} \ No newline at end of file diff --git a/Implem.Pleasanter/App_Data/Displays/ResetKambanView.json b/Implem.Pleasanter/App_Data/Displays/ResetKambanView.json new file mode 100644 index 000000000..cefb5b834 --- /dev/null +++ b/Implem.Pleasanter/App_Data/Displays/ResetKambanView.json @@ -0,0 +1,34 @@ +{ + "Id": "ResetKambanView", + "Type": 310, + "ClientScript": true, + "Languages": [ + { + "Body": "Resetting \u0022Filters\u0022 and \u0022Aggregation target\u0022 because the reference site has been changed." + }, + { + "Language": "zh", + "Body": "由于参考网站已更改,正在重置“过滤器”和“聚合目标”。" + }, + { + "Language": "ja", + "Body": "基準となるサイトが変更されるため、「フィルタ」および「集計対象」をリセットします。" + }, + { + "Language": "de", + "Body": "Zurücksetzen von \u0022Filtern\u0022 und \u0022Aggregationsziel\u0022, da sich die Referenzseite geändert hat." + }, + { + "Language": "ko", + "Body": "기준 사이트가 변경되었기 때문에 \u0022필터\u0022와 \u0022집계 대상\u0022를 재설정합니다." + }, + { + "Language": "es", + "Body": "Restableciendo \u0022Filtros\u0022 y \u0022Objetivo de agregación\u0022 porque el sitio de referencia ha cambiado." + }, + { + "Language": "vn", + "Body": "Đặt lại \u0022Bộ lọc\u0022 và \u0022Mục tiêu tổng hợp\u0022 vì trang tham chiếu đã được thay đổi." + } + ] +} \ No newline at end of file diff --git a/Implem.Pleasanter/Implem.Pleasanter.csproj b/Implem.Pleasanter/Implem.Pleasanter.csproj index aa11a211e..b21609062 100644 --- a/Implem.Pleasanter/Implem.Pleasanter.csproj +++ b/Implem.Pleasanter/Implem.Pleasanter.csproj @@ -1,13 +1,13 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 Business application platform Implem.Pleasanter - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable Linux ..\docker-compose.dcproj @@ -36,7 +36,6 @@ - NU1701 @@ -61,10 +60,10 @@ - + - + diff --git a/Implem.Pleasanter/Libraries/DataSources/Rds.cs b/Implem.Pleasanter/Libraries/DataSources/Rds.cs index 48f943baf..1d738480b 100644 --- a/Implem.Pleasanter/Libraries/DataSources/Rds.cs +++ b/Implem.Pleasanter/Libraries/DataSources/Rds.cs @@ -27996,11 +27996,11 @@ public static string Depts_DeptId_WhereLike( string name = "SearchText", bool forward = false) { - return factory.Sqls.IntegerColumnLike(tableName, "DeptId") + - (forward + return factory.Sqls.IntegerColumnLike(tableName, "DeptId") + + (forward ? string.Empty - : factory.Sqls.WhereLikeTemplateForward) + - $"@{name}{factory.Sqls.WhereLikeTemplate})"; + : factory.Sqls.WhereLikeTemplateForward) + + $"@{name}{factory.Sqls.WhereLikeTemplate})"; } public static DeptsColumnCollection DeptsColumn( @@ -39563,11 +39563,11 @@ public static string Groups_TenantId_WhereLike( string name = "SearchText", bool forward = false) { - return factory.Sqls.IntegerColumnLike(tableName, "TenantId") + - (forward + return factory.Sqls.IntegerColumnLike(tableName, "TenantId") + + (forward ? string.Empty - : factory.Sqls.WhereLikeTemplateForward) + - $"@{name}{factory.Sqls.WhereLikeTemplate})"; + : factory.Sqls.WhereLikeTemplateForward) + + $"@{name}{factory.Sqls.WhereLikeTemplate})"; } public static string Groups_GroupId_WhereLike( @@ -39576,11 +39576,11 @@ public static string Groups_GroupId_WhereLike( string name = "SearchText", bool forward = false) { - return factory.Sqls.IntegerColumnLike(tableName, "GroupId") + - (forward + return factory.Sqls.IntegerColumnLike(tableName, "GroupId") + + (forward ? string.Empty - : factory.Sqls.WhereLikeTemplateForward) + - $"@{name}{factory.Sqls.WhereLikeTemplate})"; + : factory.Sqls.WhereLikeTemplateForward) + + $"@{name}{factory.Sqls.WhereLikeTemplate})"; } public static GroupsColumnCollection GroupsColumn( @@ -70162,6 +70162,19 @@ public static string Sites_Body_WhereLike( + ")"; } + public static string Sites_SiteId_WhereLike( + ISqlObjectFactory factory, + string tableName = "Sites", + string name = "SearchText", + bool forward = false) + { + return factory.Sqls.IntegerColumnLike(tableName, "SiteId") + + (forward + ? string.Empty + : factory.Sqls.WhereLikeTemplateForward) + + $"@{name}{factory.Sqls.WhereLikeTemplate})"; + } + public static SitesColumnCollection SitesColumn( this SitesColumnCollection self, string columnName, diff --git a/Implem.Pleasanter/Libraries/DataTypes/Title.cs b/Implem.Pleasanter/Libraries/DataTypes/Title.cs index b5d6d2c72..ca2699037 100644 --- a/Implem.Pleasanter/Libraries/DataTypes/Title.cs +++ b/Implem.Pleasanter/Libraries/DataTypes/Title.cs @@ -92,6 +92,9 @@ public Title( getLinkedTitle: getLinkedTitle)) .Where(o => !o.IsNullOrEmpty()) .Join(ss.TitleSeparator); + displayValue = displayValue.Length > ss.ColumnHash["Title"].Max.ToInt() + ? displayValue.Substring(0, ss.ColumnHash["Title"].Max.ToInt()) + : displayValue; DisplayValue = GetNoTitle( context: context, displayValue: displayValue); diff --git a/Implem.Pleasanter/Libraries/General/Error.cs b/Implem.Pleasanter/Libraries/General/Error.cs index 4a447da94..2d2d3b2eb 100644 --- a/Implem.Pleasanter/Libraries/General/Error.cs +++ b/Implem.Pleasanter/Libraries/General/Error.cs @@ -24,6 +24,7 @@ public enum Types CanNotDisabled, CanNotInherit, CanNotLink, + CannotMoveMultipleSitesData, CanNotPerformed, CantSetAtTopOfSite, CustomError, @@ -181,6 +182,10 @@ public static Message Message(this Types type, Context context, params string[] return Messages.CanNotLink( context: context, data: data); + case Types.CannotMoveMultipleSitesData: + return Messages.CannotMoveMultipleSitesData( + context: context, + data: data); case Types.CanNotPerformed: return Messages.CanNotPerformed( context: context, diff --git a/Implem.Pleasanter/Libraries/Html/HtmlAttributes.cs b/Implem.Pleasanter/Libraries/Html/HtmlAttributes.cs index d9a9147bc..fe8199767 100644 --- a/Implem.Pleasanter/Libraries/Html/HtmlAttributes.cs +++ b/Implem.Pleasanter/Libraries/Html/HtmlAttributes.cs @@ -711,5 +711,15 @@ public HtmlAttributes DataReadOnly(bool value, bool _using = true) } return this; } + + public HtmlAttributes DataSiteId(string value, bool _using = true) + { + if (!value.IsNullOrEmpty() && _using) + { + Add("data-siteid"); + Add(value); + } + return this; + } } } \ No newline at end of file diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlDropDownSearches.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlDropDownSearches.cs index dacfee695..22b053189 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlDropDownSearches.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlDropDownSearches.cs @@ -1,7 +1,11 @@ -using Implem.Pleasanter.Libraries.Html; +using Implem.Libraries.Utilities; +using Implem.Pleasanter.Libraries.Html; using Implem.Pleasanter.Libraries.Requests; using Implem.Pleasanter.Libraries.Responses; using Implem.Pleasanter.Libraries.Settings; +using Implem.Pleasanter.Models; +using System.Collections.Generic; +using System.Data; using System.Linq; namespace Implem.Pleasanter.Libraries.HtmlParts { @@ -170,5 +174,41 @@ public static HtmlBuilder DropDownSearchDialogBody(this HtmlBuilder hb, Context icon: "ui-icon-search"))); } } + + public static HtmlBuilder DropDownSearchDialogBodyInheritPermission( + this HtmlBuilder hb, + Context context, + SiteSettings ss, + int offset, + int pageSize) + { + var listItemCollection = PermissionUtilities.InheritTargets( + context: context, + ss: ss, + offset: offset, + pageSize: pageSize).OptionCollection; + + return hb.FieldSelectable( + controlId: "DropDownSearchResults", + fieldCss: "field-vertical w600", + controlContainerCss: "container-selectable", + controlWrapperCss: " h300", + listItemCollection: listItemCollection, + commandOptionPositionIsTop: true, + action: "SearchDropDown", + method: "post", + commandOptionAction: () => hb + .Div(css: "command-left", action: () => hb + .TextBox( + controlId: "DropDownSearchText", + controlCss: " auto-postback always-send w200", + action: "SearchDropDown", + method: "post") + .Button( + text: Displays.Search(context: context), + controlCss: "button-icon", + onClick: "$p.send($('#DropDownSearchText'));", + icon: "ui-icon-search"))); + } } } \ No newline at end of file diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlKamban.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlKamban.cs index e7fab9e55..724cfcdb8 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlKamban.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlKamban.cs @@ -26,9 +26,11 @@ public static HtmlBuilder Kamban( bool aggregationView, bool showStatus, IEnumerable data, - bool inRange) + bool inRange, + string suffix, + long changedItemId = 0) { - return hb.Div(id: "Kamban", css: "both", action: () => + return hb.Div(id: $"Kamban{suffix}", css: "both kamban", action: () => { hb .FieldDropDown( @@ -39,7 +41,8 @@ public static HtmlBuilder Kamban( labelText: Displays.GroupByX(context: context), optionCollection: ss.KambanGroupByOptions(context: context), selectedValue: groupByX?.ColumnName, - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .FieldDropDown( context: context, controlId: "KambanGroupByY", @@ -50,7 +53,8 @@ public static HtmlBuilder Kamban( context: context, addNothing: true), selectedValue: groupByY?.ColumnName, - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .FieldDropDown( context: context, controlId: "KambanAggregateType", @@ -59,7 +63,8 @@ public static HtmlBuilder Kamban( labelText: Displays.AggregationType(context: context), optionCollection: ss.KambanAggregationTypeOptions(context: context), selectedValue: aggregateType, - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .FieldDropDown( context: context, fieldId: "KambanValueField", @@ -69,7 +74,8 @@ public static HtmlBuilder Kamban( labelText: Displays.AggregationTarget(context: context), optionCollection: ss.KambanValueOptions(context: context), selectedValue: value?.ColumnName, - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .FieldDropDown( context: context, controlId: "KambanColumns", @@ -81,21 +87,24 @@ public static HtmlBuilder Kamban( Parameters.General.KambanMaxColumns - Parameters.General.KambanMinColumns + 1) .ToDictionary(o => o.ToString(), o => o.ToString()), selectedValue: columns.ToString(), - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .FieldCheckBox( controlId: "KambanAggregationView", fieldCss: "field-auto-thin", controlCss: " auto-postback", labelText: Displays.AggregationView(context: context), _checked: aggregationView, - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .FieldCheckBox( controlId: "KambanShowStatus", fieldCss: "field-auto-thin", controlCss: " auto-postback", labelText: Displays.ShowStatus(context: context), _checked: showStatus, - method: "post") + method: "post", + _using: suffix.IsNullOrEmpty()) .KambanBody( context: context, ss: ss, @@ -108,6 +117,8 @@ public static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, + suffix: suffix, + changedItemId: changedItemId, inRange: inRange); }); } @@ -125,6 +136,7 @@ public static HtmlBuilder KambanBody( bool aggregationView, bool showStatus, IEnumerable data, + string suffix, long changedItemId = 0, bool inRange = true) { @@ -138,7 +150,8 @@ public static HtmlBuilder KambanBody( limit: Parameters.General.KambanYLimit)); return hb.Div( attributes: new HtmlAttributes() - .Id("KambanBody") + .Id($"KambanBody{suffix}") + .Class("kambanbody") .DataAction("UpdateByKamban") .DataMethod("post"), action: () => groupByX?.EditChoices( @@ -160,7 +173,26 @@ public static HtmlBuilder KambanBody( aggregationView: aggregationView, showStatus: showStatus, data: data, - changedItemId: changedItemId))); + changedItemId: changedItemId) + .Hidden( + controlId: $"KambanSuffix{suffix}", + value: !suffix.IsNullOrEmpty() + ? suffix.Replace("_", "") + : "", + _using: !suffix.IsNullOrEmpty()) + .Hidden( + controlId: $"KambanReferenceType{suffix}", + value: ss.ReferenceType) + .Hidden( + controlId: $"KambanGroupByX{suffix}", + value: groupByX?.ColumnName, + _using: !suffix.IsNullOrEmpty()) + .Hidden( + controlId: $"KambanGroupByY{suffix}", + value: groupByY?.ColumnName, + _using: !suffix.IsNullOrEmpty()) + ) + ); } private static Dictionary CorrectedChoices( @@ -195,7 +227,9 @@ private static HtmlBuilder Table( .Max() : 0; return hb.Table( - id: "Grid", + id: ss.DashboardParts.Count == 0 + ? "Grid" + : "", css: "grid fixed", action: () => hb .THead(action: () => hb @@ -397,7 +431,8 @@ private static HtmlBuilder Element( return hb.Div( attributes: new HtmlAttributes() .Class("kamban-item" + ItemChanged(data.Id, changedItemId)) - .DataId(data.Id.ToString()), + .DataId(data.Id.ToString()) + .DataSiteId(data.SiteId.ToString()), action: () => hb .Span(css: "ui-icon ui-icon-pencil") .ElementStatus( diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlNavigationMenu.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlNavigationMenu.cs index 3edde9e13..e62b83fb6 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlNavigationMenu.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlNavigationMenu.cs @@ -373,7 +373,8 @@ private static bool Using( : context.CanCreate(ss: ss, site: true) && ss.ReferenceType != "Wikis" && context.Action != "trashbox" - && ss.ReferenceType != "Dashboards"; + && ss.ReferenceType != "Dashboards" + && !(ss.ReferenceType == "Sites" && context.Action == "edit"); case "ViewModeMenu": return Def.ViewModeDefinitionCollection .Any(o => o.ReferenceType == referenceType); @@ -396,7 +397,8 @@ private static bool Using( case "SettingsMenu_Registrations": return canManageRegistrations; case "SettingsMenu_TrashBox": - return canManageTrashBox; + return canManageTrashBox + && ss.ReferenceType != "Wikis"; case "SettingsMenu_GroupTrashBox": return canManageGroupTrashBox; case "SettingsMenu_DeptTrashBox": @@ -411,11 +413,13 @@ private static bool Using( && ss.IsSite(context: context) && ss.ReferenceType == "Sites" || (context.Controller == "items" + && context.Action == "index" && ss.SiteId == 0 && context.UserSettings?.AllowCreationAtTopSite(context: context) == true); case "SettingsMenu_ExportSitePackage": return Parameters.SitePackage.Export && canManageSite + && context.Action == "index" && ss.IsSite(context: context); case "AccountMenu_ShowStartGuide": return context.UserSettings?.ShowStartGuideAvailable(context: context) == true; diff --git a/Implem.Pleasanter/Libraries/HtmlParts/HtmlScripts.cs b/Implem.Pleasanter/Libraries/HtmlParts/HtmlScripts.cs index 96f73d52c..7f0cd8440 100644 --- a/Implem.Pleasanter/Libraries/HtmlParts/HtmlScripts.cs +++ b/Implem.Pleasanter/Libraries/HtmlParts/HtmlScripts.cs @@ -112,6 +112,9 @@ public static HtmlBuilder Scripts( .Script(script: "$p.setCalendar();", _using: ss.ReferenceType == "Dashboards" && ss.DashboardParts?.Any(part=>part.Type == DashboardPartType.Calendar) == true) + .Script(script: "$p.setKamban();", + _using: ss.ReferenceType == "Dashboards" && + ss.DashboardParts?.Any(part => part.Type == DashboardPartType.Kamban) == true) .Script(script: "$p.setDashboardAsync();", _using: ss.ReferenceType == "Dashboards") .OnEditorLoad(context: context); diff --git a/Implem.Pleasanter/Libraries/Models/DropDowns.cs b/Implem.Pleasanter/Libraries/Models/DropDowns.cs index c939d68ce..b00ca17b7 100644 --- a/Implem.Pleasanter/Libraries/Models/DropDowns.cs +++ b/Implem.Pleasanter/Libraries/Models/DropDowns.cs @@ -73,6 +73,54 @@ private static string SearchDropDown( bool filter, string parentClass = "", List parentIds = null) + { + switch (controlId) + { + case "InheritPermission": + return SearchInheritPermissionDropDown( + context: context, + ss: ss); + default: + return SearchCommonDropDown( + context: context, + ss: ss, + controlId: controlId, + referenceId: referenceId, + filter: filter, + parentClass: parentClass, + parentIds: parentIds); + } + } + + private static string SearchInheritPermissionDropDown( + Context context, + SiteSettings ss) + { + var nextOffset = Paging.NextOffset( + offset: 0, + totalCount: PermissionUtilities.InheritTargets(context, ss).TotalCount, + pageSize: Parameters.General.DropDownSearchPageSize); + return new ResponseCollection(context: context) + .Html( + "#DropDownSearchDialogBody", + new HtmlBuilder().DropDownSearchDialogBodyInheritPermission( + context: context, + ss: ss, + offset: 0, + pageSize: Parameters.General.DropDownSearchPageSize)) + .Val("#DropDownSearchResultsOffset", nextOffset) + .ClearFormData("DropDownSearchResults") + .ToJson(); + } + + private static string SearchCommonDropDown( + Context context, + SiteSettings ss, + string controlId, + long referenceId, + bool filter, + string parentClass, + List parentIds) { var column = SearchDropDownColumn( context: context, @@ -82,6 +130,10 @@ private static string SearchDropDown( searchText: string.Empty, parentClass: parentClass, parentIds: parentIds); + if (!parentClass.IsNullOrEmpty() && (parentIds?.Any() ?? false) == false) + { + column.ChoiceHash.Clear(); + } var nextOffset = Paging.NextOffset( offset: 0, totalCount: column.TotalCount, @@ -107,6 +159,62 @@ private static string SearchDropDownSelectable( bool filter, string parentClass = "", List parentIds = null) + { + switch (controlId) + { + case "InheritPermission": + return SearchInheritPermissionDropDownSelectable( + context: context, + ss: ss, + searchText: searchText); + default: + return SearchCommonDropDownSelectable( + context: context, + ss: ss, + controlId: controlId, + referenceId: referenceId, + searchText: searchText, + filter: filter, + parentClass: parentClass, + parentIds: parentIds); + } + } + + private static string SearchInheritPermissionDropDownSelectable( + Context context, + SiteSettings ss, + string searchText) + { + var (optionCollection, totalCount) = PermissionUtilities.InheritTargets( + context: context, + ss: ss, + offset: 0, + pageSize: Parameters.General.DropDownSearchPageSize, + searchText: searchText); + var nextOffset = Paging.NextOffset( + offset: 0, + totalCount: totalCount, + pageSize: Parameters.General.DropDownSearchPageSize); + return new ResponseCollection(context: context) + .Html( + "#DropDownSearchResults", + new HtmlBuilder().SelectableItems( + listItemCollection: optionCollection, + alwaysDataValue: true)) + .Val("#DropDownSearchResultsOffset", nextOffset) + .ClearFormData("DropDownSearchResults") + .ToJson(); + } + + private static string SearchCommonDropDownSelectable( + Context context, + SiteSettings ss, + string controlId, + long referenceId, + string searchText, + bool filter, + string parentClass, + List parentIds) { var column = SearchDropDownColumn( context: context, @@ -150,6 +258,59 @@ private static string AppendSearchDropDownSelectable( bool filter, string parentClass = "", List parentIds = null) + { + switch (controlId) + { + case "InheritPermission": + return AppendSearchInheritPermissionDropDownSelectable( + context: context, + ss: ss, + searchText: searchText); + default: + return AppendSearchCommonDropDownSelectable( + context: context, + ss: ss, + controlId: controlId, + referenceId: referenceId, + searchText: searchText, + filter: filter, + parentClass: parentClass, + parentIds: parentIds); + } + } + + private static string AppendSearchInheritPermissionDropDownSelectable( + Context context, + SiteSettings ss, + string searchText) + { + var offset = context.Forms.Int("DropDownSearchResultsOffset"); + var (optionCollection, totalCount) = PermissionUtilities.InheritTargets( + context: context, + ss: ss, + offset: offset, + pageSize: Parameters.General.DropDownSearchPageSize, + searchText: searchText); + var nextOffset = Paging.NextOffset( + offset: offset, + totalCount: totalCount, + pageSize: Parameters.General.DropDownSearchPageSize); + return new ResponseCollection(context: context) + .Append( + "#" + context.Forms.ControlId(), + new HtmlBuilder().SelectableItems(optionCollection)) + .Val("#DropDownSearchResultsOffset", nextOffset) + .ToJson(); + } + + private static string AppendSearchCommonDropDownSelectable( + Context context, SiteSettings ss, + string controlId, + long referenceId, + string searchText, + bool filter, + string parentClass, + List parentIds) { var offset = context.Forms.Int("DropDownSearchResultsOffset"); var column = SearchDropDownColumn( @@ -301,13 +462,25 @@ public static string SelectSearchDropDown( } else { - return SelectSearchDropDownResponse( - context: context, - controlId: controlId, - column: column, - selected: selected, - filter: filter, - multiple: multiple); + switch (controlId) + { + case "InheritPermission": + return SelectSearchInheritPermissionDropDownResponse( + context: context, + ss: ss, + controlId: controlId, + selected: selected, + filter: filter, + multiple: multiple); + default: + return SelectSearchDropDownResponse( + context: context, + controlId: controlId, + column: column, + selected: selected, + filter: filter, + multiple: multiple); + } } } @@ -479,6 +652,38 @@ private static string SelectSearchDropDownResponse( .ToJson(); } + private static string SelectSearchInheritPermissionDropDownResponse( + Context context, + SiteSettings ss, + string controlId, + List selected, + bool filter, + bool multiple) + { + var optionCollection = PermissionUtilities.InheritTargets( + context: context, + ss: ss).OptionCollection; + return optionCollection?.Any() == true || !selected.Any() + ? new ResponseCollection(context: context) + .CloseDialog("#DropDownSearchDialog") + .Html("[id=\"" + controlId + "\"]", new HtmlBuilder() + .OptionCollection( + context: context, + optionCollection: optionCollection, + selectedValue: SelectSearchDropDownSelectedValue( + context: context, + selected: selected, + filter: filter, + multiple: multiple), + multiple: multiple, + insertBlank: !filter)) + .Invoke("setDropDownSearch") + .ToJson() + : new ResponseCollection(context: context) + .Message(Messages.NotFound(context: context)) + .ToJson(); + } + public static string SelectSearchDropDownSelectedValue( Context context, List selected, bool filter, bool multiple) { diff --git a/Implem.Pleasanter/Libraries/Requests/Context.cs b/Implem.Pleasanter/Libraries/Requests/Context.cs index 9a337006c..3083b700c 100644 --- a/Implem.Pleasanter/Libraries/Requests/Context.cs +++ b/Implem.Pleasanter/Libraries/Requests/Context.cs @@ -1119,8 +1119,20 @@ public CultureInfo CultureInfoCurrency(string language) { switch (language) { + case "en": + return new CultureInfo("en-US"); + case "zh": + return new CultureInfo("zh-CN"); case "ja": return new CultureInfo("ja-JP"); + case "de": + return new CultureInfo("de-DE"); + case "ko": + return new CultureInfo("ko-KR"); + case "es": + return new CultureInfo("es-ES"); + case "vn": + return new CultureInfo("vi-VN"); default: return new CultureInfo(language); } diff --git a/Implem.Pleasanter/Libraries/Responses/Displays.cs b/Implem.Pleasanter/Libraries/Responses/Displays.cs index 79ced72da..51161175a 100644 --- a/Implem.Pleasanter/Libraries/Responses/Displays.cs +++ b/Implem.Pleasanter/Libraries/Responses/Displays.cs @@ -1609,6 +1609,16 @@ public static string CanNotLink( data: data); } + public static string CannotMoveMultipleSitesData( + Context context, + params string[] data) + { + return Get( + context: context, + id: "CannotMoveMultipleSitesData", + data: data); + } + public static string CanNotPerformed( Context context, params string[] data) @@ -8119,6 +8129,16 @@ public static string ResetCalendarView( data: data); } + public static string ResetKambanView( + Context context, + params string[] data) + { + return Get( + context: context, + id: "ResetKambanView", + data: data); + } + public static string ResetOrder( Context context, params string[] data) diff --git a/Implem.Pleasanter/Libraries/Responses/Messages.cs b/Implem.Pleasanter/Libraries/Responses/Messages.cs index 9fbe300d2..635cf795c 100644 --- a/Implem.Pleasanter/Libraries/Responses/Messages.cs +++ b/Implem.Pleasanter/Libraries/Responses/Messages.cs @@ -304,6 +304,16 @@ public static Message CanNotLink(Context context, params string[] data) css: "alert-error"); } + public static Message CannotMoveMultipleSitesData(Context context, params string[] data) + { + return Get( + id: "CannotMoveMultipleSitesData", + text: Displays.CannotMoveMultipleSitesData( + context: context, + data: data), + css: "alert-error"); + } + public static Message CanNotPerformed(Context context, params string[] data) { return Get( @@ -1911,6 +1921,17 @@ public static ResponseCollection ResponseCanNotLink( target: target); } + public static ResponseCollection ResponseCannotMoveMultipleSitesData( + Context context, string target = null, params string[] data) + { + return ResponseMessage( + context: context, + message: CannotMoveMultipleSitesData( + context: context, + data: data), + target: target); + } + public static ResponseCollection ResponseCanNotPerformed( Context context, string target = null, params string[] data) { diff --git a/Implem.Pleasanter/Libraries/Responses/ResponseViewModes.cs b/Implem.Pleasanter/Libraries/Responses/ResponseViewModes.cs index d1f8507fe..ca33f28a1 100644 --- a/Implem.Pleasanter/Libraries/Responses/ResponseViewModes.cs +++ b/Implem.Pleasanter/Libraries/Responses/ResponseViewModes.cs @@ -22,14 +22,22 @@ public static ResponseCollection ViewMode( bool bodyOnly = false, string bodySelector = null, ServerScriptModelRow serverScriptModelRow = null, - HtmlBuilder body = null) + HtmlBuilder body = null, + bool replaceAllBody = false) { return res .Html( target: !bodyOnly ? "#ViewModeContainer" : bodySelector, - value: body) + value: body, + _using: !replaceAllBody || !bodyOnly) + .ReplaceAll( + target: !bodyOnly + ? "#ViewModeContainer" + : bodySelector, + value: body, + _using: replaceAllBody && bodyOnly) .View( context: context, ss: ss, diff --git a/Implem.Pleasanter/Libraries/ServerScripts/FormulaServerScriptUtilities.cs b/Implem.Pleasanter/Libraries/ServerScripts/FormulaServerScriptUtilities.cs index c2c851f0f..8702b4b2a 100644 --- a/Implem.Pleasanter/Libraries/ServerScripts/FormulaServerScriptUtilities.cs +++ b/Implem.Pleasanter/Libraries/ServerScripts/FormulaServerScriptUtilities.cs @@ -27,6 +27,8 @@ public static object Execute( using (var engine = new ScriptEngine(debug: false)) { engine.AddHostObject("model", Model); + engine.AddHostObject("context", context); + engine.AddHostType(typeof(FormulaServerScriptUtilities)); var functionScripts = GetDateScript() + GetDateDifScript() + GetDayScript() @@ -71,7 +73,17 @@ public static object Execute( + GetTruncScript() + GetAscScript() + GetJisScript() - + GetValueScript(); + + GetValueScript() + + GetTextScript() + + GetAbsScript() + + GetPowerScript() + + GetRandScript() + + GetSqrtScript() + + GetEOMonthScript() + + GetIsBlankScript() + + GetIsErrorScript() + + GetIfErrorScript() + + GetDateTimeScript(); var value = engine.Evaluate(functionScripts + formulaScript); return value == Undefined.Value ? string.Empty : value; } @@ -123,7 +135,44 @@ private static string ParseIgnoreCase(string script) .Replace("$trunc(", "$TRUNC(", StringComparison.InvariantCultureIgnoreCase) .Replace("$asc(", "$ASC(", StringComparison.InvariantCultureIgnoreCase) .Replace("$jis(", "$JIS(", StringComparison.InvariantCultureIgnoreCase) - .Replace("$value(", "$VALUE(", StringComparison.InvariantCultureIgnoreCase); + .Replace("$value(", "$VALUE(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$text(", "$TEXT(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$abs(", "$ABS(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$power(", "$POWER(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$rand(", "$RAND(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$sqrt(", "$SQRT(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$eomonth(", "$EOMONTH(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$isblank(", "$ISBLANK(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$iserror(", "$ISERROR(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$iferror(", "$IFERROR(", StringComparison.InvariantCultureIgnoreCase) + .Replace("$datetime(", "$DATETIME(", StringComparison.InvariantCultureIgnoreCase); + } + + public static string GetText(object value, string format, Context context) + { + if (string.IsNullOrEmpty(format)) + { + return string.Empty; + } + if (long.TryParse(value.ToString(), out long longValue)) + { + return longValue.ToString( + format: format, + provider: context.CultureInfoCurrency(context.Language)); + } + if (double.TryParse(value.ToString(), out double doubleValue)) + { + return doubleValue.ToString( + format: format, + provider: context.CultureInfoCurrency(context.Language)); + } + return DateTime.Parse(value.ToString()).ToString( + format: format + .Replace("Y", "y") + .Replace("D", "d") + .Replace("H", "h") + .Replace("AM/PM", "tt"), + provider: context.CultureInfoCurrency(context.Language)); } private static string GetDateScript() @@ -132,14 +181,14 @@ private static string GetDateScript() function $DATE(year, month, day) { if (arguments.length != 3) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } year = (year === undefined || year === '' || year === '0') ? 0 : year; month = (month === undefined || month === '' || month === '0') ? 0 : month; day = (day === undefined || day === '' || day === '0') ? 0 : day; if (isNaN(year) || isNaN(month) || isNaN(day)) { - throw '#NUM!'; + return '#NUM!'; } year = Number(year); month = Number(month); @@ -154,7 +203,7 @@ private static string GetDateScript() var date = new Date(year, month - 1, day); if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#NUM!'; + return '#NUM!'; } return date.getFullYear() + '/' + ('0' + (date.getMonth() + 1)).slice(-2) @@ -168,7 +217,7 @@ private static string GetDateDifScript() function $DATEDIF(startDate, endDate, unit) { if (arguments.length != 3) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } startDate = (startDate === undefined || startDate === '' || startDate === '0') ? 0 : startDate; endDate = (endDate === undefined || endDate === '' || endDate === '0') ? 0 : endDate; @@ -181,7 +230,7 @@ private static string GetDateDifScript() { return 0; } - throw '#NUM!'; + return '#NUM!'; } if (isNaN(startDate)) { @@ -194,7 +243,7 @@ private static string GetDateDifScript() } if (originStartDate !== 0 && (isNaN(startDate.getTime()) || startDate.getFullYear() < 1900 || startDate.getFullYear() > 9999)) { - throw '#VALUE!'; + return '#VALUE!'; } if (isNaN(endDate)) { @@ -208,7 +257,7 @@ private static string GetDateDifScript() if (originEndDate !== 0 && (isNaN(endDate.getTime()) || endDate.getFullYear() < 1900 || endDate.getFullYear() > 9999) || startDate.getTime() > endDate.getTime()) { - throw '#VALUE!'; + return '#VALUE!'; } switch(unit) { @@ -224,8 +273,8 @@ private static string GetDateDifScript() + 12 * (endDate.getFullYear() - startDate.getFullYear()) - (endDate.getDate() >= startDate.getDate() ? 0 : 1); case 'D': - startDate = startDate.getTime(); - endDate = endDate.getTime(); + startDate = startDate.getTime() - (startDate.getTimezoneOffset() == -402 ? -24124000 : startDate.getTimezoneOffset() * 60 * 1000); + endDate = endDate.getTime() - (endDate.getTimezoneOffset() == -402 ? -24124000 : endDate.getTimezoneOffset() * 60 * 1000); var diff = (endDate - startDate) / (1000 * 3600 * 24); return ((startDate <= endDate && endDate <= -2203915325000) || (endDate >= startDate && startDate >= -2203915324000)) @@ -254,15 +303,15 @@ private static string GetDateDifScript() endDate.setYear(startDate.getFullYear() + 1); } } - startDate = startDate.getTime(); - endDate = endDate.getTime(); + startDate = startDate.getTime() - (startDate.getTimezoneOffset() == -402 ? -24124000 : startDate.getTimezoneOffset() * 60 * 1000); + endDate = endDate.getTime() - (endDate.getTimezoneOffset() == -402 ? -24124000 : endDate.getTimezoneOffset() * 60 * 1000); var diff = (endDate - startDate) / (1000 * 3600 * 24); return ((startDate <= endDate && endDate <= -2203915325000) || (endDate >= startDate && startDate >= -2203915324000)) ? diff : (startDate < endDate ? diff - 1 : diff); default: - throw '#NUM!'; + return '#NUM!'; } }"; } @@ -273,9 +322,9 @@ private static string GetDayScript() function $DAY(date) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } - if (date === undefined || date == '' || date == 0) + if (date === undefined || date === '' || date == 0) { return 0; } @@ -290,7 +339,7 @@ private static string GetDayScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#VALUE!'; + return '#VALUE!'; } return date.getDate(); }"; @@ -302,7 +351,7 @@ private static string GetDaysScript() function $DAYS(startDate, endDate) { if (arguments.length !== 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } startDate = (startDate === undefined || startDate === '' || startDate === '0') ? 0 : startDate; endDate = (endDate === undefined || endDate === '' || startDate === '0') ? 0 : endDate; @@ -323,7 +372,7 @@ private static string GetDaysScript() } if (originStartDate !== 0 && (isNaN(startDate.getTime()) || startDate.getFullYear() < 1900 || startDate.getFullYear() > 9999)) { - throw '#VALUE!'; + return '#VALUE!'; } if (isNaN(endDate)) { @@ -336,10 +385,10 @@ private static string GetDaysScript() } if (originEndDate !== 0 && (isNaN(endDate.getTime()) || endDate.getFullYear() < 1900 || endDate.getFullYear() > 9999)) { - throw '#VALUE!'; + return '#VALUE!'; } - startDate = startDate.getTime(); - endDate = endDate.getTime(); + startDate = startDate.getTime() - (startDate.getTimezoneOffset() == -402 ? -24124000 : startDate.getTimezoneOffset() * 60 * 1000); + endDate = endDate.getTime() - (endDate.getTimezoneOffset() == -402 ? -24124000 : endDate.getTimezoneOffset() * 60 * 1000); let diff = (startDate - endDate) / (1000 * 3600 * 24), result = ((endDate <= startDate && startDate <= -2203915325000) || (startDate >= endDate && endDate >= -2203915324000)) @@ -359,7 +408,7 @@ private static string GetHourScript() function $HOUR(date) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(date === undefined || date === '' || date === '0') { return 0; @@ -387,7 +436,7 @@ private static string GetHourScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#NUM!'; + return '#NUM!'; } return date.getHours(); }"; @@ -399,7 +448,7 @@ private static string GetMinuteScript() function $MINUTE(date) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(date === undefined || date === '' || date == '0') { return 0; @@ -416,7 +465,7 @@ private static string GetMinuteScript() var times = originDate.split(':'); if (Number(times[0]) > 23 || Number(times[2]) > 59) { - throw '#VALUE!'; + return '#VALUE!'; } return Number(times[1]) % 60; } @@ -437,7 +486,7 @@ private static string GetMinuteScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#VALUE!'; + return '#VALUE!'; } return date.getMinutes(); }"; @@ -449,7 +498,7 @@ private static string GetMonthScript() function $MONTH(date) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(date === undefined || date === '' || date == '0') { return 1; @@ -465,7 +514,7 @@ private static string GetMonthScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#VALUE!'; + return '#VALUE!'; } return date.getMonth() + 1; }"; @@ -493,7 +542,7 @@ private static string GetSecondScript() function $SECOND(date) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(date === undefined || date === '' || date == '0') { return 0; @@ -521,7 +570,7 @@ private static string GetSecondScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#VALUE!'; + return '#VALUE!'; } return date.getSeconds(); }"; @@ -546,7 +595,7 @@ private static string GetYearScript() function $YEAR(date) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(date === undefined || date === '' || date == '0') { return 1900; @@ -562,7 +611,7 @@ private static string GetYearScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#VALUE!'; + return '#VALUE!'; } return date.getFullYear(); }"; @@ -575,7 +624,7 @@ private static string GetConcatScript() { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } let result = firstString === undefined ? '' : firstString; for (var i = 1; i < arguments.length; i++) @@ -595,10 +644,10 @@ private static string GetFindScript() function $FIND(findText, withinText, startNum = 1) { if (arguments.length > 3 || arguments.length < 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(isNaN(startNum) || Number(startNum) < 1) { - throw '#VALUE!'; + return '#VALUE!'; } findText = (findText == undefined) ? '' : findText; withinText = (withinText == undefined ) ? '' : withinText; @@ -608,12 +657,12 @@ private static string GetFindScript() } if((findText === '' && withinText === '' && startNum > 1) || (findText === '' && (withinText.toString().length + 1) < startNum)) { - throw '#VALUE!'; + return '#VALUE!'; } var index = withinText.toString().indexOf(findText.toString(), startNum - 1); if (index < 0) { - throw '#VALUE!'; + return '#VALUE!'; } return index + 1; }"; @@ -625,7 +674,7 @@ private static string GetLeftScript() function $LEFT(text, numChars = 1) { if (arguments.length > 2 || arguments.length < 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } numChars = Number(numChars); return text.toString().substring(0, numChars); @@ -638,7 +687,7 @@ private static string GetLenScript() function $LEN(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } text = (text == undefined) ? '' : text; return text.toString().length; @@ -651,7 +700,7 @@ private static string GetLowerScript() function $LOWER(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } text = (text == undefined) ? '' : text; return text.toString().toLowerCase(); @@ -664,18 +713,18 @@ private static string GetMidScript() function $MID(text, startNum, numChars) { if (arguments.length !== 3) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } text = (text == undefined) ? '' : text; if (isNaN(startNum) || isNaN(numChars)) { - throw '#VALUE!'; + return '#VALUE!'; } startNum = Number(startNum); numChars = Number(numChars); if (startNum < 1 || numChars < 0) { - throw '#VALUE!'; + return '#VALUE!'; } return text.toString().substring(startNum - 1, startNum - 1 + numChars); }"; @@ -687,12 +736,12 @@ private static string GetRightScript() function $RIGHT(text, numChars = 1) { if (arguments.length > 2 || arguments.length < 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } text = (text == undefined) ? '' : text; if (isNaN(numChars) || Number(numChars) < 0) { - throw '#VALUE!'; + return '#VALUE!'; } numChars = Number(numChars); return text.toString().substring(text.toString().length - numChars); @@ -705,11 +754,11 @@ private static string GetSubstituteScript() function $SUBSTITUTE(text, oldText, newtext, instanceNum) { if (arguments.length > 4 || arguments.length < 3) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if (Number(instanceNum) < 1) { - throw '#VALUE!'; + return '#VALUE!'; } text = (text == undefined) ? '' : text; oldText = (oldText == undefined) ? '' : oldText; @@ -731,7 +780,7 @@ private static string GetTrimScript() function $TRIM(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } text = (text == undefined) ? '' : text; return text.toString().trim(); @@ -744,7 +793,7 @@ private static string GetUpperScript() function $UPPER(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } text = (text == undefined) ? '' : text; return text.toString().toUpperCase(); @@ -757,7 +806,7 @@ private static string GetAndScript() function $AND(firstClause) { if (arguments.length == 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(firstClause == 0 || firstClause === 'false') { return false; @@ -784,7 +833,7 @@ private static string GetAndScript() ? true : firstClause; if (firstClause === undefined || firstClause === '' || isNaN(firstClause)) { - throw '#VALUE!'; + return '#VALUE!'; } return Boolean(firstClause); }"; @@ -796,7 +845,7 @@ private static string GetIfScript() function $IF(expression, valueIfTrue, valueIfFalse = false) { if (arguments.length > 3 || arguments.length < 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } expression = (expression === undefined || expression === '') ? false : expression; valueIfTrue = (valueIfTrue === undefined || valueIfTrue === '') ? 0 : valueIfTrue; @@ -831,7 +880,7 @@ private static string GetNotScript() function $NOT(expression) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } expression = (expression == undefined) ? '' : expression; if (!isNaN(expression)) @@ -840,7 +889,7 @@ private static string GetNotScript() } else if (typeof expression != 'boolean') { - throw '#VALUE!'; + return '#VALUE!'; } return !expression; }"; @@ -852,7 +901,7 @@ private static string GetOrScript() function $OR(expression) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } for (let i = 1; i < arguments.length; i++) { if (arguments[i] === undefined || arguments[i].toString().trim() === '') { @@ -873,7 +922,7 @@ private static string GetOrScript() ? false : expression; if (expression === undefined || expression === '' || isNaN(expression)) { - throw '#VALUE!'; + return '#VALUE!'; } return Boolean(expression); }"; @@ -886,19 +935,19 @@ private static string GetReplaceScript() { if (arguments.length !== 4) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } startNum = (startNum === undefined) ? 0 : startNum; numChars = (numChars === undefined) ? 0 : numChars; if (isNaN(startNum) || isNaN(numChars)) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } startNum = Number(startNum); numChars = Number(numChars); if (startNum < 1 || numChars < 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(oldText === undefined || oldText === '') { return newText === undefined ? '' : newText; @@ -919,21 +968,21 @@ private static string GetSearchScript() { if (arguments.length < 2 || arguments.length > 3) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } - if (start == '' || isNaN(start)) + if (start === '' || isNaN(start)) { - throw '#VALUE!'; + return '#VALUE!'; } start = Number(start); if (start < 1 || start > withinText.toString().length) { - throw '#VALUE!'; + return '#VALUE!'; } let index = withinText.toString().toLowerCase().indexOf(findText.toString().toLowerCase(), start - 1); if (index < 0) { - throw 'Not Found'; + return 'Not Found'; } return index + 1; }"; @@ -945,7 +994,7 @@ private static string GetIfsScript() function $IFS(logicalTest, valueIfTrue) { if (arguments.length === 0 || arguments.length % 2 !== 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } for (let i = 0; i < arguments.length; i = i + 2) { @@ -972,7 +1021,7 @@ private static string GetIfsScript() } } if(logicalTest === false) { - throw '#N/A'; + return '#N/A'; } }"; } @@ -983,7 +1032,7 @@ private static string GetIsEvenScript() function $ISEVEN(number) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = ( number == undefined || number === '') ? 0 : number; if (isNaN(number)) @@ -1002,7 +1051,7 @@ private static string GetIsNumberScript() { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(value === '' || value === undefined || typeof value === 'boolean') { @@ -1022,7 +1071,7 @@ private static string GetIsOddScript() function $ISODD(number) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = ( number == undefined || number === '') ? 0 : number; if (isNaN(number) && typeof number === 'string') @@ -1040,7 +1089,7 @@ private static string GetIsTextScript() function $ISTEXT(text) { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if (text === '' || text === undefined @@ -1061,14 +1110,14 @@ private static string GetModScript() function $MOD(number, divisor) { if (arguments.length !== 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } divisor = (divisor === undefined || divisor === '') ? 0 : (typeof divisor === 'boolean' && divisor) ? 1 : (typeof divisor === 'boolean' && !divisor) ? 0 : divisor; if(divisor == 0 || divisor == undefined) { - throw '#DIV/0!'; + return '#DIV/0!'; } number = (number === undefined || number === '') ? 0 : (typeof number === 'boolean' && number) ? 1 @@ -1087,7 +1136,7 @@ private static string GetOddScript() { if (arguments.length === 0) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = (number === undefined || number === '' || typeof number === 'boolean') ? 1 : number; if(number === 1) { @@ -1109,7 +1158,7 @@ private static string GetAverageScript() { if (arguments.length == 0 || arguments.length > 255) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } let sum = 0, averageCount = 0; for (let i = 0; i < arguments.length; i++) @@ -1135,7 +1184,7 @@ private static string GetAverageScript() } if (averageCount === 0) { - throw '#DIV/0!'; + return '#DIV/0!'; } return sum / averageCount; }"; @@ -1147,11 +1196,11 @@ private static string GetWeekdayScript() function $WEEKDAY(date, returnType = 1) { if (arguments.length < 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } date = (date == undefined) ? 0 : date; - if(date == '' && (returnType == '' || Number(returnType) == 0)) { - throw '#NUM!'; + if(date === '' && (returnType === '' || Number(returnType) == 0)) { + return '#NUM!'; } if (isNaN(date)) { @@ -1166,7 +1215,7 @@ private static string GetWeekdayScript() } if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) { - throw '#NUM!'; + return '#NUM!'; } returnType = Number(returnType) switch (returnType) @@ -1190,7 +1239,7 @@ private static string GetWeekdayScript() case 16: return (date.getDay() + 2) % 7 == 0 ? 7 : (date.getDay() + 2) % 7; default: - throw '#NUM!'; + return '#NUM!'; } }"; } @@ -1202,7 +1251,7 @@ private static string GetMinScript() { if (arguments.length == 0 || arguments.length > 255) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } let minValue = Number.POSITIVE_INFINITY; for (let i = 0; i < arguments.length; i++) @@ -1223,7 +1272,7 @@ private static string GetMaxScript() { if (arguments.length == 0 || arguments.length > 255) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } let maxValue = Number.NEGATIVE_INFINITY; for (let i = 0; i < arguments.length; i++) @@ -1243,7 +1292,7 @@ private static string GetRoundScript() function $ROUND(number, numDigits) { if (arguments.length !== 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = (number === undefined || number === '') ? 0 : (typeof number === 'boolean' && number) ? 1 @@ -1257,7 +1306,7 @@ private static string GetRoundScript() : numDigits; if (isNaN(Number(number)) || isNaN(Number(numDigits))) { - throw '#VALUE!'; + return '#VALUE!'; } if (number == 0 && !isNaN(Number(numDigits))) { return 0; @@ -1301,7 +1350,7 @@ private static string GetRoundUpScript() function $ROUNDUP(number, numDigits) { if (arguments.length !== 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = (number === undefined || number === '') ? 0 : (typeof number === 'boolean' && number) ? 1 @@ -1315,7 +1364,7 @@ private static string GetRoundUpScript() : numDigits; if (isNaN(Number(number)) || isNaN(Number(numDigits))) { - throw '#VALUE!'; + return '#VALUE!'; } if (number == 0 && !isNaN(Number(numDigits))) { return 0; @@ -1359,7 +1408,7 @@ private static string GetRoundDownScript() function $ROUNDDOWN(number, numDigits) { if (arguments.length !== 2) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = (number === undefined || number === '') ? 0 : (typeof number === 'boolean' && number) ? 1 @@ -1373,7 +1422,7 @@ private static string GetRoundDownScript() : numDigits; if (isNaN(Number(number)) || isNaN(Number(numDigits))) { - throw '#VALUE!'; + return '#VALUE!'; } if (number == 0 && !isNaN(Number(numDigits))) { return 0; @@ -1417,7 +1466,7 @@ private static string GetTruncScript() function $TRUNC(number, numDigits) { if (arguments.length > 2 || arguments.length < 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } number = (number === undefined || number === '') ? 0 : (typeof number === 'boolean' && number) ? 1 @@ -1431,7 +1480,7 @@ private static string GetTruncScript() : numDigits; if (isNaN(Number(number)) || isNaN(Number(numDigits))) { - throw '#VALUE!'; + return '#VALUE!'; } if (number === 0 && !isNaN(Number(numDigits))) { return 0; @@ -1459,7 +1508,7 @@ private static string GetAscScript() function $ASC(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(text === undefined || text === '') { return ''; @@ -1494,7 +1543,7 @@ private static string GetJisScript() function $JIS(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(text === undefined || text === '') { return ''; @@ -1538,10 +1587,10 @@ private static string GetValueScript() function $VALUE(text) { if (arguments.length !== 1) { - throw 'Invalid Parameter'; + return 'Invalid Parameter'; } if(typeof text === 'boolean' || text === undefined || text === '') { - throw '#VALUE!'; + return '#VALUE!'; } if (!isNaN(text)) { return Number(text); @@ -1554,7 +1603,312 @@ private static string GetValueScript() if (!isNaN(text)) { return Number(text); } - throw '#VALUE!'; + return '#VALUE!'; + }"; + } + + private static string GetTextScript() + { + return @" + function $TEXT(value, format) + { + if (arguments.length != 2 || value === undefined || format === undefined) + { + return 'Invalid Parameter'; + } + if ((value.toString().toLowerCase() === 'true' || value.toString().toLowerCase() === 'false') + && (format === '' || !isNaN(format))) + { + return value; + } + var reg = new RegExp('^0+$', 'g'); + if (reg.test(format)) + { + return FormulaServerScriptUtilities.GetText(value, '#' + format, context); + } + if (format.toString().toLowerCase() === 'true' + || format.toString().toLowerCase() === 'false' + || !isNaN(Date.parse(format))) + { + return '#VALUE!'; + } + return FormulaServerScriptUtilities.GetText(value, format, context); + }"; + } + + private static string GetAbsScript() + { + return @" + function $ABS(number) + { + if (arguments.length === 0 || number === undefined || number === '') + { + return 'Invalid Parameter'; + } + if (number.toString().toLowerCase() === 'true') + { + number = true; + } + else if (number.toString().toLowerCase() === 'false') + { + number = false; + } + if (isNaN(number)) + { + return '#VALUE!'; + } + else + { + return Math.abs(Number(number)); + } + }"; + } + + private static string GetPowerScript() + { + return @" + function $POWER(number, power) + { + if (arguments.length != 2 || number === undefined || power === undefined || number === '' || power === '') + { + return 'Invalid Parameter'; + } + if (number.toString().toLowerCase() === 'true') + { + number = true; + } + else if (number.toString().toLowerCase() === 'false') + { + number = false; + } + if (isNaN(number)) + { + return '#VALUE!'; + } + if (power.toString().toLowerCase() === 'true') + { + power = true; + } + else if (power.toString().toLowerCase() === 'false') + { + power = false; + } + if (isNaN(power)) + { + return '#VALUE!'; + } + if (((Number(number) == 0 || !number) && (Number(power) == 0 || !power)) || (Number(number) < 0 && Number(power) % 1 !== 0)) + { + return '#NUM!'; + } + var result = Math.pow(Number(number), Number(power)); + if (result == Number.POSITIVE_INFINITY || result == Number.NEGATIVE_INFINITY) + { + return '#NUM!'; + } + return result; + }"; + } + + private static string GetRandScript() + { + return @" + function $RAND() + { + return Math.random(); + }"; + } + + private static string GetSqrtScript() + { + return @" + function $SQRT(number) + { + if (arguments.length === 0 || number === undefined || number === '') + { + return 'Invalid Parameter'; + } + if (number.toString().toLowerCase() === 'true') + { + number = true; + } + else if (number.toString().toLowerCase() === 'false') + { + number = false; + } + if (isNaN(number)) + { + return '#VALUE!'; + } + else + { + if (Number(number) < 0) + { + return '#NUM!'; + } + return Math.sqrt(Number(number)); + } + }"; + } + + private static string GetEOMonthScript() + { + return @" + function $EOMONTH(start_date, months) + { + if (arguments.length != 2 || months === undefined || start_date === undefined) + { + return 'Invalid Parameter'; + } + if (start_date === '') + { + start_date = 1; + } + var datePart = start_date.split(' ')[0].toString().split('/'); + if (isNaN(start_date)) + { + if (isNaN(Date.parse(start_date))) + { + return '#VALUE!'; + } + else + { + start_date = new Date(Date.parse(start_date)); + } + } + else + { + return '#VALUE!'; + } + if (isNaN(months)) + { + if (isNaN(Date.parse(months))) + { + return '#VALUE!'; + } + else + { + months = $DAYS(months, '1900/01/01') + 1; + } + } + else + { + months = Number(months); + } + if (isNaN(start_date.getTime()) || start_date.getFullYear() < 1900 || start_date.getFullYear() > 9999) + { + return 'Invalid Parameter'; + } + if (datePart.length == 3 && datePart[2] != start_date.getDate()) + { + return '#VALUE!'; + } + var d = new Date(start_date.getFullYear(), start_date.getMonth() + Number(months) + 1, 0); + if (isNaN(d.getTime()) || d.getFullYear() < 1900 || d.getFullYear() > 9999) + { + return '#NUM!'; + } + return d.getFullYear() + + '/' + ('0' + (d.getMonth() + 1)).slice(-2) + + '/' + ('0' + d.getDate()).slice(-2); + }"; + } + + private static string GetIsBlankScript() + { + return @" + function $ISBLANK(value) + { + if (arguments.length != 1) + { + return 'Invalid Parameter'; + } + return value === undefined || value === ''; + }"; + } + + private static string GetIsErrorScript() + { + return @" + function $ISERROR(value) + { + if (arguments.length != 1) + { + return 'Invalid Parameter'; + } + return value == '#N/A' + || value == '#VALUE!' + || value == '#REF!' + || value == '#DIV/0!' + || value == '#NUM!' + || value == '#NAME?' + || value == '#NULL!' + || value == 'Invalid Parameter' + || !Number.isFinite(value); + }"; + } + + private static string GetIfErrorScript() + { + return @" + function $IFERROR(value, value_if_error) + { + if (arguments.length != 2) + { + return 'Invalid Parameter'; + } + return value === undefined || value === '' + ? 0 + : ($ISERROR(value) + ? (value_if_error === '' ? 0 : value_if_error) + : value); + }"; + } + + private static string GetDateTimeScript() + { + return @" + function $DATETIME(year, month, day, hour, minute, second) + { + if (arguments.length != 6) + { + return 'Invalid Parameter'; + } + year = (year === undefined || year === '' || year === '0') ? 0 : year; + month = (month === undefined || month === '' || month === '0') ? 0 : month; + day = (day === undefined || day === '' || day === '0') ? 0 : day; + hour = (hour === undefined || hour === '' || hour === '0') ? 0 : hour; + minute = (minute === undefined || minute === '' || minute === '0') ? 0 : minute; + second = (second === undefined || second === '' || second === '0') ? 0 : second; + if (isNaN(year) || isNaN(month) || isNaN(day) || isNaN(hour) || isNaN(minute) || isNaN(second)) + { + return '#NUM!'; + } + year = Number(year); + month = Number(month); + day = Number(day); + hour = Number(hour); + minute = Number(minute); + second = Number(second); + if (year === 0 && month === 1 && day === 0 && hour === 0 && minute === 0 && second === 0) + { + return '1900/01/00 00:00:00'; + } + if (year >= 0 && year < 1900) + { + year = 1900 + year; + } + var date = new Date(year, month - 1, day, hour, minute, second); + if (isNaN(date.getTime()) || date.getFullYear() < 1900 || date.getFullYear() > 9999) + { + return '#NUM!'; + } + return date.getFullYear() + + '/' + ('0' + (date.getMonth() + 1)).slice(-2) + + '/' + ('0' + date.getDate()).slice(-2) + + ' ' + ('0' + (date.getHours())).slice(-2) + + ':' + ('0' + (date.getMinutes())).slice(-2) + + ':' + ('0' + date.getSeconds()).slice(-2); }"; } } diff --git a/Implem.Pleasanter/Libraries/ServerScripts/ScriptEngine.cs b/Implem.Pleasanter/Libraries/ServerScripts/ScriptEngine.cs index cb586c824..a90334111 100644 --- a/Implem.Pleasanter/Libraries/ServerScripts/ScriptEngine.cs +++ b/Implem.Pleasanter/Libraries/ServerScripts/ScriptEngine.cs @@ -1,4 +1,5 @@ -using Microsoft.ClearScript.V8; +using Microsoft.ClearScript; +using Microsoft.ClearScript.V8; using System; namespace Implem.Pleasanter.Libraries.ServerScripts { @@ -22,7 +23,6 @@ public ScriptEngine(bool debug) if (debug) { flags |= V8ScriptEngineFlags.EnableDebugging - | V8ScriptEngineFlags.AwaitDebuggerAndPauseOnStart | V8ScriptEngineFlags.EnableRemoteDebugging; } v8ScriptEngine = new V8ScriptEngine(flags); @@ -43,9 +43,14 @@ public void Dispose() v8ScriptEngine?.Dispose(); } - public void Execute(string code) + public void Execute(string code, bool debug) { - v8ScriptEngine?.Execute(code); + v8ScriptEngine?.Execute( + new DocumentInfo() + { + Flags = debug ? DocumentFlags.AwaitDebuggerAndPause : DocumentFlags.None + }, + code); } public object Evaluate(string code) diff --git a/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptUtilities.cs b/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptUtilities.cs index 44bc41d7a..e90a61175 100644 --- a/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptUtilities.cs +++ b/Implem.Pleasanter/Libraries/ServerScripts/ServerScriptUtilities.cs @@ -1065,10 +1065,6 @@ public static ServerScriptModelRow Execute( { return null; } - scripts = scripts.Prepend(new ServerScript() - { - Body = ServerScriptJsLibraries.Scripts() - }).ToArray(); itemModel = itemModel ?? new BaseItemModel(); ServerScriptModelRow scriptValues = null; using (var model = new ServerScriptModel( @@ -1120,7 +1116,8 @@ public static ServerScriptModelRow Execute( engine.AddHostObject("httpClient", model.HttpClient); } engine.AddHostObject("utilities", model.Utilities); - engine.Execute(scripts.Select(o => o.Body).Join("\n")); + engine.Execute(ServerScriptJsLibraries.Scripts(), debug: false); + engine.Execute(scripts.Select(o => o.Body).Join("\n"), debug: debug); } finally { diff --git a/Implem.Pleasanter/Libraries/Settings/BackgroundServerScript.cs b/Implem.Pleasanter/Libraries/Settings/BackgroundServerScript.cs index e5f2e798f..a61b9955e 100644 --- a/Implem.Pleasanter/Libraries/Settings/BackgroundServerScript.cs +++ b/Implem.Pleasanter/Libraries/Settings/BackgroundServerScript.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Wordprocessing; -using Implem.Libraries.Utilities; +using Implem.Libraries.Utilities; using System; using System.Collections.Generic; diff --git a/Implem.Pleasanter/Libraries/Settings/DashboardPart.cs b/Implem.Pleasanter/Libraries/Settings/DashboardPart.cs index 15583707f..e1abf2064 100644 --- a/Implem.Pleasanter/Libraries/Settings/DashboardPart.cs +++ b/Implem.Pleasanter/Libraries/Settings/DashboardPart.cs @@ -53,6 +53,17 @@ public class DashboardPart : ISettingListItem public string CalendarTimePeriod { get; set; } public string CalendarFromTo { get; set; } public bool CalendarShowStatus { get; set; } + public string KambanSites { get; set; } + public List KambanSitesData { get; set; } + public string KambanGroupByX { get; set; } + public string KambanGroupByY { get; set; } + public string KambanAggregateType { get; set; } + public string KambanValue { get; set; } + public string KambanColumns { get; set; } + public bool KambanAggregationView { get; set; } + public bool KambanShowStatus { get; set; } + + public long SiteId { get; set; } public string ExtendedCss { get; set; } public List Depts { get; set; } @@ -144,6 +155,25 @@ public DashboardPart GetRecordingData(Context context) dashboardPart.View = View; if (CalendarShowStatus == true) dashboardPart.CalendarShowStatus = true; break; + case DashboardPartType.Kamban: + dashboardPart.KambanSites = KambanSites; + dashboardPart.KambanSitesData = KambanSitesData; + dashboardPart.KambanGroupByX = KambanGroupByX; + dashboardPart.KambanGroupByY = KambanGroupByY; + dashboardPart.KambanAggregateType = KambanAggregateType; + dashboardPart.KambanValue = KambanValue; + dashboardPart.KambanColumns = KambanColumns; + dashboardPart.KambanAggregationView = KambanAggregationView; + dashboardPart.KambanShowStatus = KambanShowStatus; + dashboardPart.SiteId = SiteId; + if (ss != null) + { + View = View.GetRecordingData( + context: context, + ss: ss); + } + dashboardPart.View = View; + break; } return dashboardPart; } @@ -170,6 +200,15 @@ public static DashboardPart Create( string calendarTimePeriod, string calendarFromTo, bool calendarShowStatus, + string kambanSites, + List kambanSitesData, + string kambanGroupByX, + string kambanGroupByY, + string kambanAggregateType, + string kambanValue, + string kambanColumns, + bool kambanAggregationView, + bool kambanShowStatus, string extendedCss, bool disableAsynchronousLoading, List permissions) @@ -200,6 +239,15 @@ public static DashboardPart Create( calendarTimePeriod: calendarTimePeriod, calendarFromTo: calendarFromTo, calendarShowStatus: calendarShowStatus, + kambanSites : kambanSites, + kambanSitesData: kambanSitesData, + kambanGroupByX : kambanGroupByX, + kambanGroupByY : kambanGroupByY, + kambanAggregateType : kambanAggregateType, + kambanValue: kambanValue, + kambanColumns: kambanColumns, + kambanAggregationView: kambanAggregationView, + kambanShowStatus: kambanShowStatus, extendedCss: extendedCss, disableAsynchronousLoading: disableAsynchronousLoading, permissions: permissions); @@ -230,6 +278,15 @@ public DashboardPart Update( string calendarTimePeriod, string calendarFromTo, bool calendarShowStatus, + string kambanSites, + List kambanSitesData, + string kambanGroupByX, + string kambanGroupByY, + string kambanAggregateType, + string kambanValue, + string kambanColumns, + bool kambanAggregationView, + bool kambanShowStatus, string extendedCss, bool disableAsynchronousLoading, List permissions) @@ -257,6 +314,15 @@ public DashboardPart Update( CalendarTimePeriod = calendarTimePeriod; CalendarFromTo = calendarFromTo; CalendarShowStatus = calendarShowStatus; + KambanSites = kambanSites; + KambanSitesData = kambanSitesData; + KambanGroupByX = kambanGroupByX; + KambanGroupByY = kambanGroupByY; + KambanAggregateType = kambanAggregateType; + KambanValue = kambanValue; + KambanColumns = kambanColumns; + KambanAggregationView = kambanAggregationView; + KambanShowStatus = kambanShowStatus; ExtendedCss = extendedCss; DisableAsynchronousLoading = disableAsynchronousLoading; SetSitesData(); @@ -271,6 +337,7 @@ public void SetSitesData() SetQuickAccessSitesData(); SetTimeLineSitesData(); SetCalendarSitesData(); + SetKambanSitesData(); } private void SetBaseSiteData(Context context) @@ -293,6 +360,8 @@ private List GetSiteTypeData() return TimeLineSitesData; case DashboardPartType.Calendar: return CalendarSitesData; + case DashboardPartType.Kamban: + return KambanSitesData; default: return null; } @@ -347,6 +416,20 @@ private void SetCalendarSitesData() .ToList(); } + private void SetKambanSitesData() + { + if (KambanSites == null) + { + KambanSitesData = new List(); + return; + } + KambanSitesData = KambanSites + .Split(",") + .Select(o => o.Trim()) + .Where(o => !o.IsNullOrEmpty()) + .ToList(); + } + private static SiteSettings GetBaseSiteSettings(Context context, List sites) { return GetDashboardPartTables(context: context, sites: sites) @@ -525,6 +608,8 @@ public string PartTypeString(Context context) return Displays.DashboardCustomHtml(context: context); case DashboardPartType.Calendar: return Displays.Calendar(context: context); + case DashboardPartType.Kamban: + return Displays.Kamban(context: context); default: return Displays.QuickAccess(context: context); } @@ -569,5 +654,16 @@ public void SetCalendarSites() CalendarSites = CalendarSitesData.Join(","); } } + public void SetKambanSites() + { + if (KambanSitesData == null) + { + KambanSites = string.Empty; + } + else + { + KambanSites = KambanSitesData.Join(","); + } + } } } diff --git a/Implem.Pleasanter/Libraries/Settings/DashboardPartType.cs b/Implem.Pleasanter/Libraries/Settings/DashboardPartType.cs index 86f785850..c05ad06f4 100644 --- a/Implem.Pleasanter/Libraries/Settings/DashboardPartType.cs +++ b/Implem.Pleasanter/Libraries/Settings/DashboardPartType.cs @@ -6,6 +6,7 @@ public enum DashboardPartType TimeLine = 1, Custom = 2, CustomHtml = 3, - Calendar = 4 + Calendar = 4, + Kamban = 5 } } diff --git a/Implem.Pleasanter/Libraries/Settings/DataChange.cs b/Implem.Pleasanter/Libraries/Settings/DataChange.cs index 04ddbf7d5..c9b56d5b9 100644 --- a/Implem.Pleasanter/Libraries/Settings/DataChange.cs +++ b/Implem.Pleasanter/Libraries/Settings/DataChange.cs @@ -11,6 +11,7 @@ namespace Implem.Pleasanter.Libraries.Settings { + [Serializable] public class DataChange : ISettingListItem { [JsonConverter(typeof(StringEnumConverter))] @@ -25,11 +26,21 @@ public enum Types InputDept } + public enum Periods + { + Days, + Months, + Years, + Hours, + Minutes, + Seconds + } public int Id { get; set; } - public Types Type { get; set; } + public Types? Type { get; set; } public string ColumnName { get; set; } public string BaseDateTime { get; set; } public string Value { get; set; } + public int? Delete { get; set; } public DataChange() { diff --git a/Implem.Pleasanter/Libraries/Settings/Notification.cs b/Implem.Pleasanter/Libraries/Settings/Notification.cs index 94162e4e6..e8bf74af5 100644 --- a/Implem.Pleasanter/Libraries/Settings/Notification.cs +++ b/Implem.Pleasanter/Libraries/Settings/Notification.cs @@ -44,6 +44,7 @@ public class Notification : ISettingListItem public bool? Disabled; [NonSerialized] public int Index; + public int? Delete; public enum Types : int { diff --git a/Implem.Pleasanter/Libraries/Settings/Process.cs b/Implem.Pleasanter/Libraries/Settings/Process.cs index 9b8a3b456..85b484b21 100644 --- a/Implem.Pleasanter/Libraries/Settings/Process.cs +++ b/Implem.Pleasanter/Libraries/Settings/Process.cs @@ -121,8 +121,8 @@ public void Update( string name, string displayName, ScreenTypes? screenType, - int currentStatus, - int changedStatus, + int? currentStatus, + int? changedStatus, string description, string tooltip, string confirmationMessage, @@ -140,27 +140,90 @@ public void Update( AutoNumbering autoNumbering, SettingList notifications) { - Name = name; - DisplayName = displayName; - ScreenType = screenType; - CurrentStatus = currentStatus; - ChangedStatus = changedStatus; - Description = description; - Tooltip = tooltip; - ConfirmationMessage = confirmationMessage; - SuccessMessage = successMessage; - OnClick = onClick; - ExecutionType = executionType; - ActionType = actionType; - AllowBulkProcessing = allowBulkProcessing; - ValidationType = validationType; - ValidateInputs = validateInputs; - SetPermissions(permissions: permissions); - View = view; - ErrorMessage = errorMessage; - DataChanges = dataChanges; - AutoNumbering = autoNumbering; - Notifications = notifications; + if (name != null) + { + Name = name; + } + if (displayName != null) + { + DisplayName = displayName; + } + if (screenType != null) + { + ScreenType = screenType; + } + if (currentStatus != null) + { + CurrentStatus = (int)currentStatus; + } + if (changedStatus != null) + { + ChangedStatus = (int)changedStatus; + } + if (description != null) + { + Description = description; + } + if (tooltip != null) + { + Tooltip = tooltip; + } + if (confirmationMessage != null) + { + ConfirmationMessage = confirmationMessage; + } + if (successMessage != null) + { + SuccessMessage = successMessage; + } + if (onClick != null) + { + OnClick = onClick; + } + if (executionType != null) + { + ExecutionType = executionType; + } + if (actionType != null) + { + ActionType = actionType; + } + if (allowBulkProcessing != null) + { + AllowBulkProcessing = allowBulkProcessing; + } + if (validationType != null) + { + ValidationType = validationType; + } + if (validateInputs != null) + { + ValidateInputs = validateInputs; + } + if (permissions != null) + { + SetPermissions(permissions: permissions); + } + if (view != null) + { + View = view; + } + if (errorMessage != null) + { + ErrorMessage = errorMessage; + } + if (dataChanges != null) + { + DataChanges = dataChanges; + } + if (autoNumbering != null) + { + AutoNumbering = autoNumbering; + } + if (notifications != null) + { + Notifications = notifications; + } } private void SetPermissions(List permissions) diff --git a/Implem.Pleasanter/Libraries/Settings/Reminder.cs b/Implem.Pleasanter/Libraries/Settings/Reminder.cs index cf24304f9..4eaae3b58 100644 --- a/Implem.Pleasanter/Libraries/Settings/Reminder.cs +++ b/Implem.Pleasanter/Libraries/Settings/Reminder.cs @@ -197,11 +197,15 @@ public void Remind( dataRows: dataTable.AsEnumerable().ToList(), test: test) : null; + var dataRows = dataTable.AsEnumerable().ToList(); + var notSend = dataRows.Any() + ? false + : NotSendIfNotApplicable == true; var body = reminderType != ReminderTypes.Mail ? GetBody( context: context, ss: ss, - dataRows: dataTable.AsEnumerable().ToList()) + dataRows: dataRows) : null; switch (reminderType) { @@ -241,7 +245,7 @@ public void Remind( } break; case ReminderTypes.Slack: - if (Parameters.Reminder.Slack) + if (Parameters.Reminder.Slack && !notSend) { new Slack( _context: context, @@ -251,7 +255,7 @@ public void Remind( } break; case ReminderTypes.ChatWork: - if (Parameters.Reminder.ChatWork) + if (Parameters.Reminder.ChatWork && !notSend) { new ChatWork( _context: context, @@ -263,7 +267,7 @@ public void Remind( break; case ReminderTypes.Line: case ReminderTypes.LineGroup: - if (Parameters.Reminder.Line) + if (Parameters.Reminder.Line && !notSend) { new Line( _context: context, @@ -274,7 +278,7 @@ public void Remind( } break; case ReminderTypes.Teams: - if (Parameters.Reminder.Teams) + if (Parameters.Reminder.Teams && !notSend) { new Teams( _context: context, @@ -283,7 +287,7 @@ public void Remind( } break; case ReminderTypes.RocketChat: - if (Parameters.Reminder.RocketChat) + if (Parameters.Reminder.RocketChat && !notSend) { new RocketChat( _context: context, @@ -293,7 +297,7 @@ public void Remind( } break; case ReminderTypes.InCircle: - if (Parameters.Reminder.InCircle) + if (Parameters.Reminder.InCircle && !notSend) { new InCircle( _context: context, diff --git a/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs b/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs index d99ccfaf1..6cf1d8232 100644 --- a/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs +++ b/Implem.Pleasanter/Libraries/Settings/SiteSettings.cs @@ -3325,6 +3325,17 @@ public Dictionary CalendarColumnOptions(Context context) return hash; } + public Dictionary CalendarViewTypeOptions(Context context) + { + return new Dictionary + { + { "dayGridMonth", Displays.Month(context: context) }, + { "timeGridWeek", Displays.Week(context: context) }, + { "timeGridDay", Displays.Day(context: context) }, + { "listMonth", Displays.List(context: context) } + }; + } + public Dictionary CrosstabGroupByXOptions(Context context) { return CrosstabGroupByOptions( diff --git a/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs b/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs index 5f52a4b88..8a55f250f 100644 --- a/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs +++ b/Implem.Pleasanter/Libraries/Settings/SiteSettingsUtilities.cs @@ -372,6 +372,8 @@ public static SiteSettings SysLogsSiteSettings(Context context, Sqls.TableTypes ss.SetLinks(context: context); ss.SetChoiceHash(context: context, withLink: false); ss.PermissionType = Permissions.Admins(context: context); + ss.UseFilterButton = true; + ss.AlwaysRequestSearchCondition = true; ss.TableType = tableTypes; return ss; } diff --git a/Implem.Pleasanter/Libraries/Settings/StatusControl.cs b/Implem.Pleasanter/Libraries/Settings/StatusControl.cs index e2142dedf..f8882ae81 100644 --- a/Implem.Pleasanter/Libraries/Settings/StatusControl.cs +++ b/Implem.Pleasanter/Libraries/Settings/StatusControl.cs @@ -25,13 +25,14 @@ public enum ControlConstraintsTypes public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } - public int Status { get; set; } + public int? Status { get; set; } public bool? ReadOnly { get; set; } public Dictionary ColumnHash { get; set; } public View View { get; set; } public List Depts { get; set; } public List Groups { get; set; } public List Users { get; set; } + public int? Delete { get; set; } public StatusControl() { @@ -41,7 +42,7 @@ public StatusControl( int id, string name, string description, - int status, + int? status, bool? readOnly, Dictionary columnHash, View view, @@ -60,19 +61,40 @@ public StatusControl( public void Update( string name, string description, - int status, + int? status, bool? readOnly, Dictionary columnHash, View view, List permissions) { - Name = name; - Status = status; - ReadOnly = readOnly; - ColumnHash = columnHash; - Description = description; - View = view; - SetPermissions(permissions: permissions); + if (name != null) + { + Name = name; + } + if (status != null) + { + Status = status; + } + if (readOnly != null) + { + ReadOnly = readOnly; + } + if (columnHash != null) + { + ColumnHash = columnHash; + } + if (description != null) + { + Description = description; + } + if (view != null) + { + View = view; + } + if (permissions != null) + { + SetPermissions(permissions: permissions); + } } private void SetPermissions(List permissions) diff --git a/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs b/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs index a03118b32..f2f6e9e2f 100644 --- a/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs +++ b/Implem.Pleasanter/Libraries/Settings/ValidateInput.cs @@ -1,8 +1,10 @@ using Implem.Libraries.Utilities; using Implem.Pleasanter.Interfaces; +using System; namespace Implem.Pleasanter.Libraries.Settings { + [Serializable] public class ValidateInput : ISettingListItem { public int Id { get; set; } @@ -13,6 +15,7 @@ public class ValidateInput : ISettingListItem public string RegexValidationMessage { get; set; } public decimal? Min { get; set; } public decimal? Max { get; set; } + public int? Delete{ get; set; } public ValidateInput() { diff --git a/Implem.Pleasanter/Libraries/Settings/View.cs b/Implem.Pleasanter/Libraries/Settings/View.cs index 2efe8ca57..40bee1de2 100644 --- a/Implem.Pleasanter/Libraries/Settings/View.cs +++ b/Implem.Pleasanter/Libraries/Settings/View.cs @@ -120,6 +120,7 @@ public enum ApiDataTypes : int public int? KambanColumns; public bool? KambanAggregationView; public bool? KambanShowStatus; + public string KambanSuffix; public List Depts; public List Groups; public List Users; @@ -472,6 +473,11 @@ public int GetKambanColumns() return KambanColumns ?? Parameters.General.KambanColumns; } + public string GetKambanSuffix() + { + return KambanSuffix; + } + private ViewModeDefinition Definition(SiteSettings ss, string name) { return Def.ViewModeDefinitionCollection.FirstOrDefault(o => @@ -938,6 +944,18 @@ public void SetByForm( AddCalendarViewTypeHash(value: context.Forms.Data($"CalendarViewType{CalendarSuffix}"), key: $"CalendarViewType{CalendarSuffix}"); } } + if (ss.DashboardParts?.FirstOrDefault()?.Type == DashboardPartType.Kamban) + { + var dashboardPart = ss.DashboardParts.FirstOrDefault(); + KambanSuffix = $"_{dashboardPart.Id}"; + KambanGroupByX = dashboardPart.KambanGroupByX; + KambanGroupByY = dashboardPart.KambanGroupByY; + KambanAggregateType = dashboardPart.KambanAggregateType; + KambanValue = dashboardPart.KambanValue; + KambanColumns = dashboardPart.KambanColumns.ToInt(); + KambanAggregationView = dashboardPart.KambanAggregationView; + KambanShowStatus = dashboardPart.KambanShowStatus; + } break; } } diff --git a/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs b/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs index 5a6c179fa..8f6840b1a 100644 --- a/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs +++ b/Implem.Pleasanter/Libraries/SitePackages/Utilities.cs @@ -717,8 +717,6 @@ internal static Dictionary SitePackageSelectableOptions( ? "-true" : "-false"), new ControlData(name, title: dataRow.String("ReferenceType"), - css: " ui-icon ui-icon-folder-open", - style: " ui-icon ui-icon-folder-collapsed", order: listItemCollection.Count + 1)); if (dataRow.String("ReferenceType") == "Sites") { @@ -814,7 +812,7 @@ private static SitePackage GetSitePackage(Context context, SiteSettings ss, Site && (context.ContractSettings.Export == false || !context.CanExport(ss: currentSs))) { - return null; + site.IncludeData = false; } } return new SitePackage( diff --git a/Implem.Pleasanter/Libraries/ViewModes/CalendarElement.cs b/Implem.Pleasanter/Libraries/ViewModes/CalendarElement.cs index 1fb872a64..263ade034 100644 --- a/Implem.Pleasanter/Libraries/ViewModes/CalendarElement.cs +++ b/Implem.Pleasanter/Libraries/ViewModes/CalendarElement.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Office2010.ExcelAc; -using Implem.Libraries.Utilities; +using Implem.Libraries.Utilities; using System; using System.Collections.Generic; diff --git a/Implem.Pleasanter/Libraries/ViewModes/FullCalendarElement.cs b/Implem.Pleasanter/Libraries/ViewModes/FullCalendarElement.cs index 62895810a..90aae0417 100644 --- a/Implem.Pleasanter/Libraries/ViewModes/FullCalendarElement.cs +++ b/Implem.Pleasanter/Libraries/ViewModes/FullCalendarElement.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Office2010.ExcelAc; -using Implem.Libraries.Utilities; +using Implem.Libraries.Utilities; using System; using System.Collections.Generic; diff --git a/Implem.Pleasanter/Libraries/ViewModes/KambanElement.cs b/Implem.Pleasanter/Libraries/ViewModes/KambanElement.cs index 8b7713340..55a262dd1 100644 --- a/Implem.Pleasanter/Libraries/ViewModes/KambanElement.cs +++ b/Implem.Pleasanter/Libraries/ViewModes/KambanElement.cs @@ -5,6 +5,7 @@ namespace Implem.Pleasanter.Libraries.ViewModes public class KambanElement { public long Id; + public long SiteId; public string Title; public DateTime StartTime; public CompletionTime CompletionTime; diff --git a/Implem.Pleasanter/Models/Dashboards/DashboardModel.cs b/Implem.Pleasanter/Models/Dashboards/DashboardModel.cs index 6f8b49201..b6393c54a 100644 --- a/Implem.Pleasanter/Models/Dashboards/DashboardModel.cs +++ b/Implem.Pleasanter/Models/Dashboards/DashboardModel.cs @@ -1763,40 +1763,45 @@ public void SetByFormula(Context context, SiteSettings ss) ss: ss, formulaScript: formulaSet.FormulaScript, calculationMethod: formulaSet.CalculationMethod); - try + var value = FormulaServerScriptUtilities.Execute( + context: context, + ss: ss, + itemModel: this, + formulaScript: formulaSet.FormulaScript); + switch (value) { - var value = FormulaServerScriptUtilities.Execute( - context: context, - ss: ss, - itemModel: this, - formulaScript: formulaSet.FormulaScript); - var formData = new Dictionary - { - { $"Dashboards_{columnName}", value.ToString() } - }; - SetByFormData( - context: context, - ss: ss, - formData: formData); - if (ss.OutputFormulaLogs == true) - { - context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); - context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); - context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); - } + case "#N/A": + case "#VALUE!": + case "#REF!": + case "#DIV/0!": + case "#NUM!": + case "#NAME?": + case "#NULL!": + case "Invalid Parameter": + if (formulaSet.IsDisplayError == true) + { + throw new Exception($"Formula error {value}"); + } + new SysLogModel( + context: context, + method: nameof(SetByFormula), + message: $"Formula error {value}", + sysLogType: SysLogModel.SysLogTypes.Execption); + break; } - catch (Exception exception) + var formData = new Dictionary { - if (formulaSet.IsDisplayError == true) - { - throw new Exception($"Formula error {exception.Message}"); - } - new SysLogModel( - context: context, - method: nameof(SetByFormula), - message: $"Formula error {exception.Message}", - errStackTrace: exception.StackTrace, - sysLogType: SysLogModel.SysLogTypes.Execption); + { $"Dashboards_{columnName}", value.ToString() } + }; + SetByFormData( + context: context, + ss: ss, + formData: formData); + if (ss.OutputFormulaLogs == true) + { + context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); + context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); + context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); } } }); diff --git a/Implem.Pleasanter/Models/Dashboards/DashboardUtilities.cs b/Implem.Pleasanter/Models/Dashboards/DashboardUtilities.cs index f3cdad8a3..38d047fe4 100644 --- a/Implem.Pleasanter/Models/Dashboards/DashboardUtilities.cs +++ b/Implem.Pleasanter/Models/Dashboards/DashboardUtilities.cs @@ -116,6 +116,11 @@ private static string ViewModeTemplate( context: context, ss: ss, dashboardPart: dashboardPart); + case DashboardPartType.Kamban: + return KambanLayout( + context: context, + ss: ss, + dashboardPart: dashboardPart); default: return new DashboardPartLayout(); }; @@ -1374,6 +1379,11 @@ public static string DashboardPartJson( context: context, ss: ss, dashboardPart: dashboardPart).Content; + case DashboardPartType.Kamban: + return KambanLayout( + context: context, + ss: ss, + dashboardPart: dashboardPart).Content; default: return null; } @@ -1383,6 +1393,7 @@ public static string DashboardPartJson( target: $"#DashboardPart_{dashboardPartId}", value: dashboardPartLayout.FirstOrDefault()) .Invoke("setCalendar", dashboardPartId.ToString()) + .Invoke("setKamban", dashboardPartId.ToString()) .ToJson(); } @@ -2304,5 +2315,189 @@ private static DashboardPartLayout AsynchronousLoadingLayout(DashboardPart dashb Content = AsynchronousLoading }; } + + /// + /// Fixed: + /// + private static DashboardPartLayout KambanLayout( + Context context, + SiteSettings ss, + DashboardPart dashboardPart) + { + var hb = new HtmlBuilder(); + var kambanHtml = GetKambanRecords( + context: context, + dashboardPart: dashboardPart); + var kamban = hb + .Div( + id: $"DashboardPart_{dashboardPart.Id}", + attributes: new HtmlAttributes().DataId(dashboardPart.Id.ToString()), + css: "dashboard-kamban-container " + dashboardPart.ExtendedCss, + action: () => + { + if (dashboardPart.ShowTitle == true) + { + hb.Div( + css: "dashboard-part-title", + action: () => hb.Text(dashboardPart.Title)); + } + hb.Raw(text: kambanHtml); + }).ToString(); + return new DashboardPartLayout() + { + Id = dashboardPart.Id, + X = dashboardPart.X, + Y = dashboardPart.Y, + W = dashboardPart.Width, + H = dashboardPart.Height, + Content = kamban + }; + } + + /// + /// Fixed: + /// + private static string GetKambanRecords( + Context context, + DashboardPart dashboardPart) + { + var ss = SiteSettingsUtilities.Get( + context: context, + siteId: dashboardPart.SiteId, + setAllChoices: true); + ss.IntegratedSites = dashboardPart.KambanSitesData; + ss.SetSiteIntegration(context: context); + ss.SetDashboardParts(dashboardPart: dashboardPart); + if (ss.ReferenceType == "Issues") + { + return IssueUtilities.Kamban(context: context, ss: ss); + } + else if (ss.ReferenceType == "Results") + { + return ResultUtilities.Kamban(context: context, ss: ss); + } + else + { + return null; + } + } + + /// + /// Fixed: + /// + public static string UpdateByKamban( + Context context, + SiteSettings ss) + { + var matchingKey = context.Forms.Keys.FirstOrDefault(x => x.StartsWith("KambanSuffix_")); + DashboardPart dashboardPart = ss.DashboardParts.FirstOrDefault(x => x.Id == context.Forms.Data(matchingKey).ToInt()); + var currentSs = SiteSettingsUtilities.Get( + context: context, + siteId: context.Forms.Long("SiteId"), + setAllChoices: true); + currentSs.IntegratedSites = dashboardPart.KambanSitesData; + currentSs.SetSiteIntegration(context: context); + currentSs.SetDashboardParts(dashboardPart: dashboardPart); + if( currentSs.AllowedIntegratedSites?.Count > 1) + { + return Messages.ResponseCannotMoveMultipleSitesData(context: context).ToJson(); + } + var hb = new HtmlBuilder(); + switch (currentSs.ReferenceType) + { + case "Issues": + var issues = IssueUtilities.UpdateByKamban(context: context, ss: currentSs); + var issueKamban = hb.Div( + id: $"DashboardPart_{dashboardPart.Id}", + attributes: new HtmlAttributes().DataId(dashboardPart.Id.ToString()), + css: "dashboard-kamban-container " + dashboardPart.ExtendedCss, + action: () => + { + if (dashboardPart.ShowTitle == true) + { + hb.Div( + css: "dashboard-part-title", + action: () => hb.Text(dashboardPart.Title)); + } + hb.Raw(text: issues); + }).ToString(); + List> issuesJson = Jsons.Deserialize>>(issues); + if (issuesJson != null) + { + Dictionary messageElement = issuesJson.Find(item => item.ContainsValue("Message")); + if (messageElement != null) + { + Dictionary messageValue = Jsons.Deserialize>(messageElement["Value"]); + return new ResponseCollection(context: context) + .Message(message: new Message(messageValue["Id"], messageValue["Text"], messageValue["Css"])) + .Invoke("setKamban", dashboardPart.Id.ToString()) + .ToJson(); + } + } + var issueModel = new IssueModel( + context: context, + ss: currentSs, + issueId: context.Forms.Long("KambanId"), + formData: context.Forms); + return new ResponseCollection(context: context) + .ReplaceAll( + target: $"#DashboardPart_{dashboardPart.Id}", + value: issueKamban) + .Message(context.ErrorData.Type != Error.Types.None + ? context.ErrorData.Message(context: context) + : Messages.Updated( + context: context, + data: issueModel.Title.MessageDisplay(context: context))) + .Invoke("setKamban", dashboardPart.Id.ToString()) + .ToJson(); + case "Results": + var results = ResultUtilities.UpdateByKamban(context: context, ss: currentSs); + var resultKamban = hb.Div( + id: $"DashboardPart_{dashboardPart.Id}", + attributes: new HtmlAttributes().DataId(dashboardPart.Id.ToString()), + css: "dashboard-kamban-container " + dashboardPart.ExtendedCss, + action: () => + { + if (dashboardPart.ShowTitle == true) + { + hb.Div( + css: "dashboard-part-title", + action: () => hb.Text(dashboardPart.Title)); + } + hb.Raw(text: results); + }).ToString(); + List> resultsJson = Jsons.Deserialize>>(results); + if (resultsJson != null) + { + Dictionary messageElement = resultsJson.Find(item => item.ContainsValue("Message")); + if (messageElement != null) + { + Dictionary messageValue = Jsons.Deserialize>(messageElement["Value"]); + return new ResponseCollection(context: context) + .Message(message: new Message(messageValue["Id"], messageValue["Text"], messageValue["Css"])) + .Invoke("setKamban", dashboardPart.Id.ToString()) + .ToJson(); + } + } + var resultModel = new ResultModel( + context: context, + ss: currentSs, + resultId: context.Forms.Long("KambanId"), + formData: context.Forms); + return new ResponseCollection(context: context) + .Html( + target: $"#DashboardPart_{dashboardPart.Id}", + value: resultKamban) + .Message(context.ErrorData.Type != Error.Types.None + ? context.ErrorData.Message(context: context) + : Messages.Updated( + context: context, + data: resultModel.Title.MessageDisplay(context: context))) + .Invoke("setKamban", dashboardPart.Id.ToString()) + .ToJson(); + default: + return Messages.ResponseNotFound(context: context).ToJson(); + } + } } } diff --git a/Implem.Pleasanter/Models/Depts/DeptUtilities.cs b/Implem.Pleasanter/Models/Depts/DeptUtilities.cs index c1d82e695..7525f50c9 100644 --- a/Implem.Pleasanter/Models/Depts/DeptUtilities.cs +++ b/Implem.Pleasanter/Models/Depts/DeptUtilities.cs @@ -3130,5 +3130,16 @@ private static int PhysicalBulkDelete( }).Count.ToInt(); return count; } + + public static int CountByIds(Context context, SiteSettings ss, List ids) + { + return Repository.ExecuteScalar_int( + context: context, + statements: Rds.SelectDepts( + column: Rds.DeptsColumn() + .DeptsCount(), + where: Rds.DeptsWhere() + .DeptId_In(value: ids))); + } } } diff --git a/Implem.Pleasanter/Models/Groups/GroupUtilities.cs b/Implem.Pleasanter/Models/Groups/GroupUtilities.cs index 3dadab506..c09dcb313 100644 --- a/Implem.Pleasanter/Models/Groups/GroupUtilities.cs +++ b/Implem.Pleasanter/Models/Groups/GroupUtilities.cs @@ -4225,5 +4225,16 @@ private static int PhysicalBulkDelete( }).Count.ToInt(); return count; } + + public static int CountByIds(Context context, SiteSettings ss, List ids) + { + return Repository.ExecuteScalar_int( + context: context, + statements: Rds.SelectGroups( + column: Rds.GroupsColumn() + .GroupsCount(), + where: Rds.GroupsWhere() + .GroupId_In(value: ids))); + } } } diff --git a/Implem.Pleasanter/Models/Issues/IssueModel.cs b/Implem.Pleasanter/Models/Issues/IssueModel.cs index 5ba7ee363..5edbba1eb 100644 --- a/Implem.Pleasanter/Models/Issues/IssueModel.cs +++ b/Implem.Pleasanter/Models/Issues/IssueModel.cs @@ -3715,40 +3715,45 @@ public void SetByFormula(Context context, SiteSettings ss) ss: ss, formulaScript: formulaSet.FormulaScript, calculationMethod: formulaSet.CalculationMethod); - try + var value = FormulaServerScriptUtilities.Execute( + context: context, + ss: ss, + itemModel: this, + formulaScript: formulaSet.FormulaScript); + switch (value) { - var value = FormulaServerScriptUtilities.Execute( - context: context, - ss: ss, - itemModel: this, - formulaScript: formulaSet.FormulaScript); - var formData = new Dictionary - { - { $"Issues_{columnName}", value.ToString() } - }; - SetByFormData( - context: context, - ss: ss, - formData: formData); - if (ss.OutputFormulaLogs == true) - { - context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); - context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); - context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); - } + case "#N/A": + case "#VALUE!": + case "#REF!": + case "#DIV/0!": + case "#NUM!": + case "#NAME?": + case "#NULL!": + case "Invalid Parameter": + if (formulaSet.IsDisplayError == true) + { + throw new Exception($"Formula error {value}"); + } + new SysLogModel( + context: context, + method: nameof(SetByFormula), + message: $"Formula error {value}", + sysLogType: SysLogModel.SysLogTypes.Execption); + break; } - catch (Exception exception) + var formData = new Dictionary { - if (formulaSet.IsDisplayError == true) - { - throw new Exception($"Formula error {exception.Message}"); - } - new SysLogModel( - context: context, - method: nameof(SetByFormula), - message: $"Formula error {exception.Message}", - errStackTrace: exception.StackTrace, - sysLogType: SysLogModel.SysLogTypes.Execption); + { $"Issues_{columnName}", value.ToString() } + }; + SetByFormData( + context: context, + ss: ss, + formData: formData); + if (ss.OutputFormulaLogs == true) + { + context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); + context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); + context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); } } }); diff --git a/Implem.Pleasanter/Models/Issues/IssueUtilities.cs b/Implem.Pleasanter/Models/Issues/IssueUtilities.cs index ac3caac31..c05c95ead 100644 --- a/Implem.Pleasanter/Models/Issues/IssueUtilities.cs +++ b/Implem.Pleasanter/Models/Issues/IssueUtilities.cs @@ -8875,19 +8875,31 @@ public static string Kamban(Context context, SiteSettings ss) var serverScriptModelRow = ss.GetServerScriptModelRow( context: context, view: view); - return hb.ViewModeTemplate( - context: context, - ss: ss, - view: view, - viewMode: viewMode, - serverScriptModelRow: serverScriptModelRow, - viewModeBody: () => hb - .Kamban( - context: context, - ss: ss, - view: view, - bodyOnly: false, - inRange: inRange)); + if (ss.DashboardParts?.Any() != true) + { + return hb.ViewModeTemplate( + context: context, + ss: ss, + view: view, + viewMode: viewMode, + serverScriptModelRow: serverScriptModelRow, + viewModeBody: () => hb + .Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: false, + inRange: inRange)); + } + else + { + return hb.Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: false, + inRange: inRange).ToString(); + } } public static string KambanJson( @@ -8900,59 +8912,79 @@ public static string KambanJson( return Messages.ResponseHasNotPermission(context: context).ToJson(); } var view = Views.GetBySession(context: context, ss: ss); - var bodyOnly = context.Forms.ControlId().StartsWith("Kamban"); + var bodyOnly = ss.DashboardParts?.Any() == true + ? false + : context.Forms.ControlId().StartsWith("Kamban"); var res = new ResponseCollection(context: context); + var suffix = view.GetKambanSuffix(); if (context.ErrorData.Type != Error.Types.None) { res.Message(context.ErrorData.Message(context: context)); } - if (InRange( - context: context, - ss: ss, - view: view, - limit: Parameters.General.KambanLimit)) + if (ss.DashboardParts?.Any() != true) { - var body = new HtmlBuilder().Kamban( + if (InRange( context: context, ss: ss, view: view, - bodyOnly: bodyOnly, - changedItemId: updated - ? context.Forms.Long("KambanId") - : 0); - return res - .ViewMode( + limit: Parameters.General.KambanLimit)) + { + var body = new HtmlBuilder().Kamban( context: context, ss: ss, view: view, - invoke: "setKamban", bodyOnly: bodyOnly, - bodySelector: "#KambanBody", - body: body) - .Events("on_kamban_load") - .ToJson(); + changedItemId: updated + ? context.Forms.Long("KambanId") + : 0); + return res + .ViewMode( + context: context, + ss: ss, + view: view, + invoke: "setKamban", + bodyOnly: bodyOnly, + bodySelector: $"#KambanBody{suffix}", + body: body, + replaceAllBody: true) + .Events("on_kamban_load") + .ToJson(); + } + else + { + var body = new HtmlBuilder().Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: bodyOnly, + inRange: false); + return res + .ViewMode( + context: context, + ss: ss, + view: view, + message: Messages.TooManyCases( + context: context, + data: Parameters.General.KambanLimit.ToString()), + bodyOnly: bodyOnly, + bodySelector: $"#KambanBody{suffix}", + body: body, + replaceAllBody: true) + .Events("on_kamban_load") + .ToJson(); + } } else { var body = new HtmlBuilder().Kamban( - context: context, - ss: ss, - view: view, - bodyOnly: bodyOnly, - inRange: false); - return res - .ViewMode( context: context, ss: ss, view: view, - message: Messages.TooManyCases( - context: context, - data: Parameters.General.KambanLimit.ToString()), bodyOnly: bodyOnly, - bodySelector: "#KambanBody", - body: body) - .Events("on_kamban_load") - .ToJson(); + changedItemId: updated + ? context.Forms.Long("KambanId") + : 0); + return body.ToString(); } } @@ -8997,6 +9029,7 @@ private static HtmlBuilder Kamban( groupByX: groupByX, groupByY: groupByY, value: value); + var suffix = view.GetKambanSuffix(); return !bodyOnly ? hb.Kamban( context: context, @@ -9010,7 +9043,9 @@ private static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, - inRange: inRange) + inRange: inRange, + suffix: suffix, + changedItemId: changedItemId) : hb.KambanBody( context: context, ss: ss, @@ -9023,6 +9058,7 @@ private static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, + suffix: suffix, changedItemId: changedItemId, inRange: inRange); } @@ -9037,6 +9073,7 @@ private static HtmlBuilder Kamban( { var column = Rds.IssuesColumn() .IssueId() + .SiteId() .Status() .ItemTitle(ss.ReferenceType) .Add( @@ -9048,9 +9085,13 @@ private static HtmlBuilder Kamban( .Add( context: context, column: value); - var where = view.Where( + var where = ss.DashboardParts?.Any() == true + ? ss.DashboardParts[0].View.Where(context: context, ss: ss) + : new SqlWhereCollection(); + where = view.Where( context: context, - ss: ss); + ss: ss, + where: where); var param = view.Param( context: context, ss: ss); @@ -9071,6 +9112,7 @@ private static HtmlBuilder Kamban( .Select(o => new Libraries.ViewModes.KambanElement() { Id = o.Long("IssueId"), + SiteId = o.Long("SiteId"), Title = o.String("ItemTitle"), Status = new Status(o.Int("Status")), GroupX = groupByX?.ConvertIfUserColumn(o), diff --git a/Implem.Pleasanter/Models/Items/ItemModel.cs b/Implem.Pleasanter/Models/Items/ItemModel.cs index feef01a71..bfa333079 100644 --- a/Implem.Pleasanter/Models/Items/ItemModel.cs +++ b/Implem.Pleasanter/Models/Items/ItemModel.cs @@ -2823,6 +2823,10 @@ public string UpdateByKamban(Context context) setAllChoices: true); switch (Site.ReferenceType) { + case "Dashboards": + return DashboardUtilities.UpdateByKamban( + context: context, + ss: Site.SiteSettings); case "Issues": return IssueUtilities.UpdateByKamban( context: context, diff --git a/Implem.Pleasanter/Models/Permissions/PermissionUtilities.cs b/Implem.Pleasanter/Models/Permissions/PermissionUtilities.cs index fbc2a40ab..61ba1be19 100644 --- a/Implem.Pleasanter/Models/Permissions/PermissionUtilities.cs +++ b/Implem.Pleasanter/Models/Permissions/PermissionUtilities.cs @@ -164,11 +164,11 @@ public static HtmlBuilder Inherit( context: context, controlId: "InheritPermission", fieldCss: "field-auto-thin", - controlCss: " auto-postback", + controlCss: " auto-postback search", labelText: Displays.InheritPermission(context: context), optionCollection: InheritTargets( context: context, - ss: siteModel.SiteSettings), + ss: siteModel.SiteSettings).OptionCollection, selectedValue: siteModel.InheritPermission.ToString(), action: "SetPermissions", method: "post") @@ -178,42 +178,81 @@ public static HtmlBuilder Inherit( /// /// Fixed: /// - private static Dictionary InheritTargets( - Context context, SiteSettings ss) + public static (Dictionary OptionCollection, int TotalCount) InheritTargets( + Context context, + SiteSettings ss, + int offset = 0, + int pageSize = 0, + string searchText = "") { - return new Dictionary + Dictionary dictionary = new Dictionary(); + if (offset == 0) { - { ss.SiteId.ToString(), new ControlData(Displays.NotInheritPermission(context: context)) }, - }.AddRange(InheritTargetsDataRows(context: context, ss: ss) - .ToDictionary( + dictionary.Add(ss.SiteId.ToString(), new ControlData(Displays.NotInheritPermission(context: context))); + } + var (dataRows, totalCount) = InheritTargetsDataRows( + context: context, + ss: ss, + offset: offset, + pageSize: pageSize, + searchText: searchText); + dictionary.AddRange( + dataRows.ToDictionary( o => o["SiteId"].ToString(), o => new ControlData($"[{o["SiteId"]}] {o["Title"]}"))); + return (dictionary, totalCount); } /// /// Fixed: /// - public static EnumerableRowCollection InheritTargetsDataRows( - Context context, SiteSettings ss) + public static (EnumerableRowCollection DataRows, int TotalCount) InheritTargetsDataRows( + Context context, + SiteSettings ss, + int offset = 0, + int pageSize = 0, + string searchText = "") { - return Repository.ExecuteTable( - context: context, - statements: Rds.SelectSites( + var where = Rds.SitesWhere() + .TenantId(context.TenantId) + .SiteId(ss.SiteId, _operator: "<>") + .InheritPermission(raw: "\"Sites\".\"SiteId\"") + .Add( + raw: Def.Sql.CanReadSites, + _using: !context.HasPrivilege) + .SqlWhereLike( + tableName: "Sites", + name: "SearchText", + searchText: searchText, + clauseCollection: new List() + { + Rds.Sites_Title_WhereLike(factory: context), + Rds.Sites_SiteId_WhereLike(factory: context) + }); + var statements = new List() + { + Rds.SelectSites( + offset: offset, + pageSize: pageSize, + dataTableName: "Main", column: Rds.SitesColumn() .SiteId() .Title(), join: Rds.SitesJoinDefault(), - where: Rds.SitesWhere() - .TenantId(context.TenantId) - .SiteId(ss.SiteId, _operator: "<>") - .InheritPermission(raw: "\"Sites\".\"SiteId\"") - .Add( - raw: Def.Sql.CanReadSites, - _using: !context.HasPrivilege), + where: where, orderBy: Rds.SitesOrderBy() .Title() - .SiteId())) - .AsEnumerable(); + .SiteId()), + Rds.SelectCount( + tableName: "Sites", + join: Rds.SitesJoinDefault(), + where: where) + }; + var dataSet = Repository.ExecuteDataSet( + context: context, + statements: statements.ToArray()); + var totalCount = Rds.Count(dataSet); + return (dataSet.Tables["Main"].AsEnumerable(), totalCount); } /// diff --git a/Implem.Pleasanter/Models/Results/ResultModel.cs b/Implem.Pleasanter/Models/Results/ResultModel.cs index a270b50ee..79f7341bb 100644 --- a/Implem.Pleasanter/Models/Results/ResultModel.cs +++ b/Implem.Pleasanter/Models/Results/ResultModel.cs @@ -3382,40 +3382,45 @@ public void SetByFormula(Context context, SiteSettings ss) ss: ss, formulaScript: formulaSet.FormulaScript, calculationMethod: formulaSet.CalculationMethod); - try + var value = FormulaServerScriptUtilities.Execute( + context: context, + ss: ss, + itemModel: this, + formulaScript: formulaSet.FormulaScript); + switch (value) { - var value = FormulaServerScriptUtilities.Execute( - context: context, - ss: ss, - itemModel: this, - formulaScript: formulaSet.FormulaScript); - var formData = new Dictionary - { - { $"Results_{columnName}", value.ToString() } - }; - SetByFormData( - context: context, - ss: ss, - formData: formData); - if (ss.OutputFormulaLogs == true) - { - context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); - context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); - context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); - } + case "#N/A": + case "#VALUE!": + case "#REF!": + case "#DIV/0!": + case "#NUM!": + case "#NAME?": + case "#NULL!": + case "Invalid Parameter": + if (formulaSet.IsDisplayError == true) + { + throw new Exception($"Formula error {value}"); + } + new SysLogModel( + context: context, + method: nameof(SetByFormula), + message: $"Formula error {value}", + sysLogType: SysLogModel.SysLogTypes.Execption); + break; } - catch (Exception exception) + var formData = new Dictionary { - if (formulaSet.IsDisplayError == true) - { - throw new Exception($"Formula error {exception.Message}"); - } - new SysLogModel( - context: context, - method: nameof(SetByFormula), - message: $"Formula error {exception.Message}", - errStackTrace: exception.StackTrace, - sysLogType: SysLogModel.SysLogTypes.Execption); + { $"Results_{columnName}", value.ToString() } + }; + SetByFormData( + context: context, + ss: ss, + formData: formData); + if (ss.OutputFormulaLogs == true) + { + context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); + context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); + context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); } } }); diff --git a/Implem.Pleasanter/Models/Results/ResultUtilities.cs b/Implem.Pleasanter/Models/Results/ResultUtilities.cs index ec9cbe5c6..d3197e054 100644 --- a/Implem.Pleasanter/Models/Results/ResultUtilities.cs +++ b/Implem.Pleasanter/Models/Results/ResultUtilities.cs @@ -8109,19 +8109,31 @@ public static string Kamban(Context context, SiteSettings ss) var serverScriptModelRow = ss.GetServerScriptModelRow( context: context, view: view); - return hb.ViewModeTemplate( - context: context, - ss: ss, - view: view, - viewMode: viewMode, - serverScriptModelRow: serverScriptModelRow, - viewModeBody: () => hb - .Kamban( - context: context, - ss: ss, - view: view, - bodyOnly: false, - inRange: inRange)); + if (ss.DashboardParts?.Any() != true) + { + return hb.ViewModeTemplate( + context: context, + ss: ss, + view: view, + viewMode: viewMode, + serverScriptModelRow: serverScriptModelRow, + viewModeBody: () => hb + .Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: false, + inRange: inRange)); + } + else + { + return hb.Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: false, + inRange: inRange).ToString(); + } } public static string KambanJson( @@ -8134,59 +8146,79 @@ public static string KambanJson( return Messages.ResponseHasNotPermission(context: context).ToJson(); } var view = Views.GetBySession(context: context, ss: ss); - var bodyOnly = context.Forms.ControlId().StartsWith("Kamban"); + var bodyOnly = ss.DashboardParts?.Any() == true + ? false + : context.Forms.ControlId().StartsWith("Kamban"); var res = new ResponseCollection(context: context); + var suffix = view.GetKambanSuffix(); if (context.ErrorData.Type != Error.Types.None) { res.Message(context.ErrorData.Message(context: context)); } - if (InRange( - context: context, - ss: ss, - view: view, - limit: Parameters.General.KambanLimit)) + if (ss.DashboardParts?.Any() != true) { - var body = new HtmlBuilder().Kamban( + if (InRange( context: context, ss: ss, view: view, - bodyOnly: bodyOnly, - changedItemId: updated - ? context.Forms.Long("KambanId") - : 0); - return res - .ViewMode( + limit: Parameters.General.KambanLimit)) + { + var body = new HtmlBuilder().Kamban( context: context, ss: ss, view: view, - invoke: "setKamban", bodyOnly: bodyOnly, - bodySelector: "#KambanBody", - body: body) - .Events("on_kamban_load") - .ToJson(); + changedItemId: updated + ? context.Forms.Long("KambanId") + : 0); + return res + .ViewMode( + context: context, + ss: ss, + view: view, + invoke: "setKamban", + bodyOnly: bodyOnly, + bodySelector: $"#KambanBody{suffix}", + body: body, + replaceAllBody: true) + .Events("on_kamban_load") + .ToJson(); + } + else + { + var body = new HtmlBuilder().Kamban( + context: context, + ss: ss, + view: view, + bodyOnly: bodyOnly, + inRange: false); + return res + .ViewMode( + context: context, + ss: ss, + view: view, + message: Messages.TooManyCases( + context: context, + data: Parameters.General.KambanLimit.ToString()), + bodyOnly: bodyOnly, + bodySelector: $"#KambanBody{suffix}", + body: body, + replaceAllBody: true) + .Events("on_kamban_load") + .ToJson(); + } } else { var body = new HtmlBuilder().Kamban( - context: context, - ss: ss, - view: view, - bodyOnly: bodyOnly, - inRange: false); - return res - .ViewMode( context: context, ss: ss, view: view, - message: Messages.TooManyCases( - context: context, - data: Parameters.General.KambanLimit.ToString()), bodyOnly: bodyOnly, - bodySelector: "#KambanBody", - body: body) - .Events("on_kamban_load") - .ToJson(); + changedItemId: updated + ? context.Forms.Long("KambanId") + : 0); + return body.ToString(); } } @@ -8231,6 +8263,7 @@ private static HtmlBuilder Kamban( groupByX: groupByX, groupByY: groupByY, value: value); + var suffix = view.GetKambanSuffix(); return !bodyOnly ? hb.Kamban( context: context, @@ -8244,7 +8277,9 @@ private static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, - inRange: inRange) + inRange: inRange, + suffix: suffix, + changedItemId: changedItemId) : hb.KambanBody( context: context, ss: ss, @@ -8257,6 +8292,7 @@ private static HtmlBuilder Kamban( aggregationView: aggregationView, showStatus: showStatus, data: data, + suffix: suffix, changedItemId: changedItemId, inRange: inRange); } @@ -8271,6 +8307,7 @@ private static HtmlBuilder Kamban( { var column = Rds.ResultsColumn() .ResultId() + .SiteId() .Status() .ItemTitle(ss.ReferenceType) .Add( @@ -8282,9 +8319,13 @@ private static HtmlBuilder Kamban( .Add( context: context, column: value); - var where = view.Where( + var where = ss.DashboardParts?.Any() == true + ? ss.DashboardParts[0].View.Where(context: context, ss: ss) + : new SqlWhereCollection(); + where = view.Where( context: context, - ss: ss); + ss: ss, + where: where); var param = view.Param( context: context, ss: ss); @@ -8305,6 +8346,7 @@ private static HtmlBuilder Kamban( .Select(o => new Libraries.ViewModes.KambanElement() { Id = o.Long("ResultId"), + SiteId = o.Long("SiteId"), Title = o.String("ItemTitle"), Status = new Status(o.Int("Status")), GroupX = groupByX?.ConvertIfUserColumn(o), diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingPermission.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingPermission.cs new file mode 100644 index 000000000..ede5e882c --- /dev/null +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingPermission.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; + +namespace Implem.Pleasanter.Models +{ + [Serializable] + public class ApiSiteSettingPermission + { + public List Depts { get; set; } + public List Groups { get; set; } + public List Users { get; set; } + + public ApiSiteSettingPermission() + { + } + } +} diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingValidators.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingValidators.cs index 50bc3db84..9f1685632 100644 --- a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingValidators.cs +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ApiSiteSettingValidators.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; namespace Implem.Pleasanter.Models { @@ -14,7 +15,8 @@ public static class ApiSiteSettingValidators public static ErrorData OnChageSiteSettingByApi( string referenceType, SiteSettings ss, - SiteSettingsApiModel siteSettingsModel) + SiteSettingsApiModel siteSettingsModel, + Context context) { if (siteSettingsModel == null) { @@ -58,9 +60,25 @@ public static ErrorData OnChageSiteSettingByApi( baseApiValidator = ApiSiteSettingValidators.OnSiteSettingByApi( apiSiteSettingBaseProperties: baseApiProperties, ss: ss, - siteSettingType: "Scripts"); + siteSettingType: "Styles"); + if (baseApiValidator.Type != Error.Types.None) { return baseApiValidator; } + } + if (siteSettingsModel.Processes != null) + { + baseApiValidator = ApiSiteSettingValidators.ProcessesValidator( + processes: siteSettingsModel.Processes, + ss: ss, + context: context); if (baseApiValidator.Type != Error.Types.None) { return baseApiValidator; } } + if (siteSettingsModel.StatusControls != null) + { + baseApiValidator = ApiSiteSettingValidators.StatusControlValidator( + statusControls: siteSettingsModel.StatusControls, + ss: ss, + context: context); + if (baseApiValidator.Type != Error.Types.None) { return baseApiValidator; } + } return new ErrorData(type: Error.Types.None); } @@ -75,8 +93,9 @@ public static ErrorData OnSiteSettingByApi( } foreach (var apiSiteSetting in apiSiteSettingBaseProperties) { - if (apiSiteSetting.Id == null) return new ErrorData(type: Error.Types.NotFound); - var scriptModel = ss.Scripts?.FirstOrDefault(o => o.Id == apiSiteSetting.Id.ToInt()); + if (apiSiteSetting.Id == null) { + return new ErrorData(type: Error.Types.NotFound); + } if (apiSiteSetting.Delete.ToInt() != ApiSiteSetting.DeleteFlag.IsDelete.ToInt() && string.IsNullOrEmpty(apiSiteSetting.Title)) { @@ -94,5 +113,260 @@ public static ErrorData OnSiteSettingByApi( } return new ErrorData(type: Error.Types.None); } + + public static ErrorData ProcessesValidator( + List processes, + SiteSettings ss, + Context context) + { + var valid = new ErrorData(type: Error.Types.None); + processes.ForEach(process => + { + Type objectType = process.GetType(); + PropertyInfo[] properties = objectType.GetProperties(); + foreach (var property in properties) + { + var value = property.GetValue(process); + switch (property.Name) + { + case "Id": + if (value.ToInt() == 0) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + else if (process.Delete == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + return; + } + break; + case "Name": + if (string.IsNullOrEmpty((string)value)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "Delete": + if (value != null && value.ToInt() != ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "ScreenType": + if (value != null && !Enum.IsDefined(typeof(Process.ScreenTypes), value)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "ActionType": + if (value != null && !Enum.IsDefined(typeof(Process.ActionTypes), value)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "ExecutionType": + if (value != null && !Enum.IsDefined(typeof(Process.ExecutionTypes), value)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "ValidationType": + if (value != null && !Enum.IsDefined(typeof(Process.ValidationTypes), value)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "ValidateInputs": + if (process.ValidateInputs != null) + { + foreach (var validateInput in process.ValidateInputs) + { + if (validateInput.Id.ToInt() != 0 && validateInput.Delete.ToInt() == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + continue; + } + if (validateInput.Id.ToInt() == 0 + || (validateInput.Delete != null && validateInput.Delete.ToInt() != ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + || string.IsNullOrEmpty(validateInput.ColumnName)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + } + } + break; + case "DataChanges": + if (process.DataChanges != null) + { + foreach (var dataChange in process.DataChanges) + { + if (dataChange.Id.ToInt() != 0 && dataChange.Delete.ToInt() == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + continue; + } + if (dataChange.Id.ToInt() == 0 + || (dataChange.Delete != null && dataChange.Delete.ToInt() != ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + || string.IsNullOrEmpty(dataChange.Type.ToString()) + || string.IsNullOrEmpty(dataChange.ColumnName)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + if (!Enum.IsDefined(typeof(DataChange.Types), dataChange.Type) + || ((dataChange.Type.ToString() == "InputDate" || dataChange.Type.ToString() == "InputDateTime") + && (string.IsNullOrEmpty(dataChange.Value) + || !decimal.TryParse(dataChange.Value?.Split_1st(), out decimal result) + || !Enum.IsDefined(typeof(DataChange.Periods), dataChange.Value?.Split_2nd())))) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + } + } + break; + case "Notifications": + if (process.Notifications != null) + { + foreach (var notification in process.Notifications) + { + if (notification.Id.ToInt() != 0 && notification.Delete.ToInt() == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + continue; + } + if (notification.Id.ToInt() == 0 + || !Enum.IsDefined(typeof(Notification.Types), notification.Type) + || (notification.Delete != null && notification.Delete.ToInt() != ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + || string.IsNullOrEmpty(notification.Subject) + || string.IsNullOrEmpty(notification.Address) + || string.IsNullOrEmpty(notification.Body)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + } + } + break; + case "Permission": + if (process.Permission?.Users != null + && process.Permission.Users.Count() != UserUtilities.CountByIds( + context: context, + ss: ss, + ids: process.Permission.Users)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + if (process.Permission?.Groups != null + && process.Permission.Groups.Count() != GroupUtilities.CountByIds( + context: context, + ss: ss, + ids: process.Permission.Groups)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + if (process.Permission?.Depts != null + && process.Permission.Depts.Count() != DeptUtilities.CountByIds( + context: context, + ss: ss, + ids: process.Permission.Depts)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + } + } + }); + return valid; + } + + public static ErrorData StatusControlValidator( + List statusControls, + SiteSettings ss, + Context context) + { + var valid = new ErrorData(type: Error.Types.None); + statusControls.ForEach(statusControl => + { + Type objectType = statusControl.GetType(); + PropertyInfo[] properties = objectType.GetProperties(); + foreach (var property in properties) + { + var value = property.GetValue(statusControl); + switch (property.Name) + { + case "Id": + if (value.ToInt() == 0) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "Name": + if (statusControl.Delete != ApiSiteSetting.DeleteFlag.IsDelete.ToInt() && string.IsNullOrEmpty((string)value)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + case "Delete": + if (value != null && value.ToInt() != ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + else if (value.ToInt() == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + return; + } + break; + case "Permission": + if (statusControl.Permission?.Users != null + && statusControl.Permission.Users.Count() != UserUtilities.CountByIds( + context: context, + ss: ss, + ids: statusControl.Permission.Users)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + if (statusControl.Permission?.Groups != null + && statusControl.Permission.Groups.Count() != GroupUtilities.CountByIds( + context: context, + ss: ss, + ids: statusControl.Permission.Groups)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + if (statusControl.Permission?.Depts != null + && statusControl.Permission.Depts.Count() != DeptUtilities.CountByIds( + context: context, + ss: ss, + ids: statusControl.Permission.Depts)) + { + valid = new ErrorData(type: Error.Types.NotFound); + return; + } + break; + } + } + }); + return valid; + } + + public static ErrorData StatusControlsValidtor( + List statusControls, + SiteSettings ss) + { + return new ErrorData(type: Error.Types.None); + } } } diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/HtmlApiSettingModel.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/HtmlApiSettingModel.cs index 0d0368be9..84550f348 100644 --- a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/HtmlApiSettingModel.cs +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/HtmlApiSettingModel.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Vml.Spreadsheet; -using Implem.Pleasanter.Models.Shared; +using Implem.Pleasanter.Models.Shared; using System; using System.Collections.Generic; diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ProcessApiSettingModel.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ProcessApiSettingModel.cs new file mode 100644 index 000000000..fcc2a0dad --- /dev/null +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ProcessApiSettingModel.cs @@ -0,0 +1,43 @@ +using Implem.Pleasanter.Libraries.Settings; +using System; +using System.Collections.Generic; + +namespace Implem.Pleasanter.Models.ApiSiteSettings +{ + [Serializable] + public class ProcessApiSettingModel + { + public int Id { get; set; } + public string Name { get; set; } + public string DisplayName { get; set; } + public int? ScreenType { get; set; } + public int? CurrentStatus { get; set; } + public int? ChangedStatus { get; set; } + public string Description { get; set; } + public string Tooltip { get; set; } + public string ConfirmationMessage { get; set; } + public string SuccessMessage { get; set; } + public string OnClick { get; set; } + public int? ExecutionType { get; set; } + public int? ActionType { get; set; } + public bool? AllowBulkProcessing { get; set; } + public int? ValidationType { get; set; } + public SettingList ValidateInputs { get; set; } + public List Depts { get; set; } + public List Groups { get; set; } + public List Users { get; set; } + public View View { get; set; } + public string ErrorMessage { get; set; } + public SettingList DataChanges { get; set; } + public AutoNumbering AutoNumbering { get; set; } + public ApiSiteSettingPermission Permission { get; set; } + public SettingList Notifications { get; set; } + [NonSerialized] + public bool? MatchConditions; + public int? Delete; + + public ProcessApiSettingModel() + { + } + } +} diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ScriptApiSettingModel.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ScriptApiSettingModel.cs index 12b653c05..bce32f59e 100644 --- a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ScriptApiSettingModel.cs +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/ScriptApiSettingModel.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Vml.Spreadsheet; -using Implem.Pleasanter.Models.Shared; +using Implem.Pleasanter.Models.Shared; using System; using System.Collections.Generic; diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/SiteSettingsApiModel.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/SiteSettingsApiModel.cs index d3f00a73b..dd71dc34c 100644 --- a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/SiteSettingsApiModel.cs +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/SiteSettingsApiModel.cs @@ -1,5 +1,4 @@ -using Implem.Pleasanter.Models.Shared; -using System; +using System; using System.Collections.Generic; namespace Implem.Pleasanter.Models.ApiSiteSettings @@ -11,6 +10,8 @@ public class SiteSettingsApiModel public List Scripts { get; set; } public List Styles { get; set; } public List Htmls { get; set; } + public List Processes { get; set; } + public List StatusControls { get; set; } public SiteSettingsApiModel() { } diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StatusControlApiSettingModel.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StatusControlApiSettingModel.cs new file mode 100644 index 000000000..2b511178d --- /dev/null +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StatusControlApiSettingModel.cs @@ -0,0 +1,24 @@ +using Implem.Pleasanter.Libraries.Settings; +using System; +using System.Collections.Generic; + +namespace Implem.Pleasanter.Models.ApiSiteSettings +{ + [Serializable] + public class StatusControlApiSettingModel + { + public int Id { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public int? Status { get; set; } + public bool? ReadOnly { get; set; } + public Dictionary ColumnHash { get; set; } + public View View { get; set; } + public ApiSiteSettingPermission Permission { get; set; } + public int? Delete { get; set; } + + public StatusControlApiSettingModel() + { + } + } +} diff --git a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StyleApiSettingModel.cs b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StyleApiSettingModel.cs index ca66be142..5352eb2fa 100644 --- a/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StyleApiSettingModel.cs +++ b/Implem.Pleasanter/Models/Sites/ApiSiteSettings/StyleApiSettingModel.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Vml.Spreadsheet; -using Implem.Pleasanter.Models.Shared; +using Implem.Pleasanter.Models.Shared; using System; using System.Collections.Generic; diff --git a/Implem.Pleasanter/Models/Sites/DemoApiModel.cs b/Implem.Pleasanter/Models/Sites/DemoApiModel.cs index b3e8e4312..576aee8ac 100644 --- a/Implem.Pleasanter/Models/Sites/DemoApiModel.cs +++ b/Implem.Pleasanter/Models/Sites/DemoApiModel.cs @@ -1,5 +1,4 @@ -using DocumentFormat.OpenXml.Wordprocessing; -using Implem.Libraries.Utilities; +using Implem.Libraries.Utilities; using Implem.Pleasanter.Libraries.Requests; using Implem.Pleasanter.Libraries.Responses; using Implem.Pleasanter.Libraries.Settings; diff --git a/Implem.Pleasanter/Models/Sites/SiteModel.cs b/Implem.Pleasanter/Models/Sites/SiteModel.cs index 9ca6bad7e..64f05cf8c 100644 --- a/Implem.Pleasanter/Models/Sites/SiteModel.cs +++ b/Implem.Pleasanter/Models/Sites/SiteModel.cs @@ -20,7 +20,7 @@ using System.Data; using System.Data.Common; using System.Linq; -using static Implem.Pleasanter.Libraries.ServerScripts.ServerScriptModel; + namespace Implem.Pleasanter.Models { [Serializable] @@ -2538,6 +2538,144 @@ public void UpsertHtmlByApi( } } + public void UpsertProcessByApi( + SiteSettings siteSetting, + List processesApiSiteSetting, + Context context) + { + List deleteSelected = new List(); + processesApiSiteSetting.ForEach(processApiSiteSetting => + { + var currentProcess = siteSetting.Processes?. + FirstOrDefault(o => o.Id == processApiSiteSetting.Id.ToInt()); + if (processApiSiteSetting.Delete.ToInt() == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + deleteSelected.Add(processApiSiteSetting.Id.ToInt()); + } + else if (currentProcess != null) + { + currentProcess.Update( + name: processApiSiteSetting.Name, + displayName: processApiSiteSetting.DisplayName, + screenType: processApiSiteSetting.ScreenType?.ToString().ToEnum(), + currentStatus: processApiSiteSetting.CurrentStatus, + changedStatus: processApiSiteSetting.ChangedStatus, + description: processApiSiteSetting.Description, + tooltip: processApiSiteSetting.Tooltip, + confirmationMessage: processApiSiteSetting.ConfirmationMessage, + successMessage: processApiSiteSetting.SuccessMessage, + onClick: processApiSiteSetting.OnClick, + executionType: processApiSiteSetting.ExecutionType?.ToString().ToEnum(), + actionType: processApiSiteSetting.ActionType?.ToString().ToEnum(), + allowBulkProcessing: processApiSiteSetting.AllowBulkProcessing, + validationType: processApiSiteSetting.ValidationType?.ToString().ToEnum(), + validateInputs: ParseValidateInputs( + validateInputs: processApiSiteSetting.ValidateInputs, + process: currentProcess), + permissions: processApiSiteSetting.Permission != null ? ParsePermissions( + apiSettingPermission: processApiSiteSetting.Permission, + ss: siteSetting, + target: currentProcess) : null, + view: processApiSiteSetting.View, + errorMessage: processApiSiteSetting.ErrorMessage, + dataChanges: ParseDataChanges( + dataChanges: processApiSiteSetting.DataChanges, + process: currentProcess), + autoNumbering: processApiSiteSetting.AutoNumbering, + notifications: ParseNotifications( + notifications: processApiSiteSetting.Notifications, + process: currentProcess)); + } + else + { + SiteSettings.Processes.Add(new Process( + id: processApiSiteSetting.Id, + name: processApiSiteSetting.Name, + displayName: processApiSiteSetting.DisplayName, + screenType: processApiSiteSetting.ScreenType?.ToString().ToEnum(), + currentStatus: processApiSiteSetting.CurrentStatus != null ? (int)processApiSiteSetting.CurrentStatus : default, + changedStatus: processApiSiteSetting.ChangedStatus != null ? (int)processApiSiteSetting.ChangedStatus : default, + description: processApiSiteSetting.Description, + tooltip: processApiSiteSetting.Tooltip, + confirmationMessage: processApiSiteSetting.ConfirmationMessage, + successMessage: processApiSiteSetting.SuccessMessage, + onClick: processApiSiteSetting.OnClick, + executionType: processApiSiteSetting.ExecutionType?.ToString().ToEnum(), + actionType: processApiSiteSetting.ActionType?.ToString().ToEnum(), + allowBulkProcessing: processApiSiteSetting.AllowBulkProcessing, + validationType: processApiSiteSetting.ValidationType?.ToString().ToEnum(), + validateInputs: ParseValidateInputs( + validateInputs: processApiSiteSetting.ValidateInputs, + process: currentProcess), + permissions: ParsePermissions( + apiSettingPermission: processApiSiteSetting.Permission, + ss: siteSetting), + view: processApiSiteSetting.View, + errorMessage: processApiSiteSetting.ErrorMessage, + dataChanges: ParseDataChanges( + dataChanges: processApiSiteSetting.DataChanges, + process: currentProcess), + autoNumbering: processApiSiteSetting.AutoNumbering, + notifications: ParseNotifications( + notifications: processApiSiteSetting.Notifications, + process: currentProcess))); + } + }); + if (deleteSelected.Count() != 0) + { + siteSetting.Processes.Delete(deleteSelected); + } + } + + public void UpsertStatusControlByApi( + SiteSettings siteSetting, + List statusControlSettings, + Context context) + { + List deleteSelected = new List(); + statusControlSettings.ForEach(statusControlSetting => + { + var statusControl = siteSetting.StatusControls?. + FirstOrDefault(o => o.Id == statusControlSetting.Id.ToInt()); + if (statusControlSetting.Delete.ToInt() == ApiSiteSetting.DeleteFlag.IsDelete.ToInt()) + { + deleteSelected.Add(statusControlSetting.Id.ToInt()); + } + else if (statusControl != null) + { + statusControl.Update( + name: statusControlSetting.Name, + description: statusControlSetting.Description, + status: statusControlSetting.Status, + readOnly: statusControlSetting.ReadOnly, + view: statusControlSetting.View, + columnHash: statusControlSetting.ColumnHash, + permissions: statusControlSetting.Permission != null ? ParsePermissions( + apiSettingPermission: statusControlSetting.Permission, + ss: siteSetting, + target: statusControl) : null); + } + else + { + SiteSettings.StatusControls.Add(new StatusControl( + id: statusControlSetting.Id, + name: statusControlSetting.Name, + description: statusControlSetting.Description, + status: statusControlSetting.Status, + readOnly: statusControlSetting.ReadOnly, + view: statusControlSetting.View, + columnHash: statusControlSetting.ColumnHash, + permissions: ParsePermissions( + apiSettingPermission: statusControlSetting.Permission, + ss: siteSetting))); + } + }); + if (deleteSelected.Count() != 0) + { + siteSetting.StatusControls.Delete(deleteSelected); + } + } + /// /// Fixed: /// @@ -3384,9 +3522,19 @@ private void SetSiteSettings(Context context, ResponseCollection res) res: res); break; case "AddDashboardPartViewFilter": - var BaseSiteId = !context.Forms.Data("DashboardPartBaseSiteId").IsNullOrEmpty() - ? context.Forms.Long("DashboardPartBaseSiteId") - : context.Forms.Long("DashboardPartCalendarBaseSiteId"); + long BaseSiteId = 0; + if (!context.Forms.Data("DashboardPartCalendarBaseSiteId").IsNullOrEmpty()) + { + BaseSiteId = context.Forms.Long("DashboardPartCalendarBaseSiteId"); + } + else if (!context.Forms.Data("DashboardPartKambanBaseSiteId").IsNullOrEmpty()) + { + BaseSiteId = context.Forms.Long("DashboardPartKambanBaseSiteId"); + } + else + { + BaseSiteId = context.Forms.Long("DashboardPartBaseSiteId"); + } var ss = SiteSettingsUtilities.Get( context: context, siteId: BaseSiteId); @@ -3416,6 +3564,16 @@ private void SetSiteSettings(Context context, ResponseCollection res) context: context, res: res); break; + case "EditKambanSites": + OpenDashboardPartKambanSitesDialog( + context: context, + res: res); + break; + case "UpdateDashboardPartKambanSites": + UpdateDashboardPartKambanSites( + context: context, + res: res); + break; case "ClearDashboardView": ClearDashboardView( context: context, @@ -3426,6 +3584,11 @@ private void SetSiteSettings(Context context, ResponseCollection res) context: context, res: res); break; + case "ClearDashboardKambanView": + ClearDashboardKambanView( + context: context, + res: res); + break; case "UpdateDashboardPartLayouts": UpdatedashboardPartLayouts(context: context); break; @@ -8027,6 +8190,18 @@ private void OpenDashboardPartCalendarSitesDialog(Context context, ResponseColle dashboardCalendarSites: context.Forms.Data("DashboardPartCalendarSites"))); } + /// + /// Fixed: + /// + private void OpenDashboardPartKambanSitesDialog(Context context, ResponseCollection res) + { + res.Html("#DashboardPartKambanSitesDialog", SiteUtilities.DashboardPartKambanSitesDialog( + context: context, + ss: SiteSettings, + dashboardPartId: context.Forms.Int("DashboardPartId"), + dashboardKambanSites: context.Forms.Data("DashboardPartKambanSites"))); + } + /// /// Fixed: /// @@ -8088,6 +8263,15 @@ private void AddDashboardPart(Context context, ResponseCollection res, string co calendarFromTo: context.Forms.Data("DashboardPartCalendarFromTo"), calendarShowStatus: context.Forms.Bool("CalendarShowStatus"), calendarType: context.Forms.Data("DashboardPartCalendarType").ToEnum(), + kambanSites: context.Forms.Data("DashboardPartKambanSites"), + kambanSitesData: context.Forms.Data("DashboardPartKambanSites").Split(',').ToList(), + kambanGroupByX: context.Forms.Data("DashboardPartKambanGroupByX"), + kambanGroupByY: context.Forms.Data("DashboardPartKambanGroupByY"), + kambanAggregateType: context.Forms.Data("DashboardPartKambanAggregateType"), + kambanValue: context.Forms.Data("DashboardPartKambanValue"), + kambanColumns: context.Forms.Data("DashboardPartKambanColumns"), + kambanAggregationView: context.Forms.Bool("DashboardPartKambanAggregationView"), + kambanShowStatus: context.Forms.Bool("DashboardPartKambanShowStatus"), extendedCss: context.Forms.Data("DashboardPartExtendedCss"), disableAsynchronousLoading: context.Forms.Bool("DisableAsynchronousLoading"), permissions: DashboardPartPermissions(context: context)); @@ -8153,6 +8337,15 @@ private void UpdateDashboardPart(Context context, ResponseCollection res) calendarFromTo: context.Forms.Data("DashboardPartCalendarFromTo"), calendarShowStatus: context.Forms.Bool("CalendarShowStatus"), calendarType: context.Forms.Data("DashboardPartCalendarType").ToEnum(), + kambanSites: context.Forms.Data("DashboardPartKambanSites"), + kambanSitesData: context.Forms.Data("DashboardPartKambanSites").Split(',').ToList(), + kambanGroupByX: context.Forms.Data("DashboardPartKambanGroupByX"), + kambanGroupByY: context.Forms.Data("DashboardPartKambanGroupByY"), + kambanAggregateType: context.Forms.Data("DashboardPartKambanAggregateType"), + kambanValue: context.Forms.Data("DashboardPartKambanValue"), + kambanColumns: context.Forms.Data("DashboardPartKambanColumns"), + kambanAggregationView: context.Forms.Bool("DashboardPartKambanAggregationView"), + kambanShowStatus: context.Forms.Bool("DashboardPartKambanShowStatus"), extendedCss: context.Forms.Data("DashboardPartExtendedCss"), disableAsynchronousLoading: context.Forms.Bool("DisableAsynchronousLoading"), permissions: DashboardPartPermissions(context: context)); @@ -8389,6 +8582,61 @@ private void UpdateDashboardPartCalendarSites(Context context, ResponseCollectio } } + /// + /// Fixed: + /// + private void UpdateDashboardPartKambanSites(Context context, ResponseCollection res) + { + var savedKambanSites = context.Forms.Data("SavedDashboardPartKambanSites"); + var kambanSites = context.Forms.Data("DashboardPartKambanSitesEdit"); + var savedSs = DashboardPart.GetBaseSiteSettings( + context: context, + sitesString: savedKambanSites); + var currentSs = DashboardPart.GetBaseSiteSettings( + context: context, + sitesString: kambanSites); + if (currentSs == null || currentSs.SiteId == 0) + { + res.Message( + message: new Message( + id: "InvalidKambanSites", + text: Displays.InvalidTimeLineSites(context: context), + css: "alert-error"), + target: "#DashboardPartKambanSitesMessage"); + } + else if (savedSs == null || savedSs?.SiteId == 0 || savedSs?.SiteId == currentSs?.SiteId) + { + res + .Set( + target: "#DashboardPartKambanSites", + value: kambanSites) + .Set( + target: "#DashboardPartKambanBaseSiteId", + value: currentSs.SiteId) + .Add( + method: "SetValue", + target: "#DashboardPartKambanSitesValue", + value: kambanSites) + .CloseDialog( + target: "#DashboardPartKambanSitesDialog"); + if (savedSs == null || savedSs?.SiteId == 0) + { + ClearDashboardKambanView(context: context, res: res); + } + } + else + { + res + .Invoke( + methodName: "confirmKambanSites", + args: new + { + kambanSites, + baseSiteId = currentSs.SiteId + }.ToJson()); + } + } + /// /// Fixed: /// @@ -8484,6 +8732,49 @@ private void ClearDashboardCalendarView(Context context, ResponseCollection res) o => o.Key, o => new ControlData(o.Value)))); } + /// + /// Fixed: + /// + private void ClearDashboardKambanView(Context context, ResponseCollection res) + { + var currentSs = DashboardPart.GetBaseSiteSettings( + context: context, + context.Forms.Data("DashboardPartKambanSitesEdit")); + if (currentSs == null) + { + res.Message( + new Message( + "InvalidKambanSites", + Displays.InvalidTimeLineSites(context: context), + "alert-error")); + return; + } + var dashboardPart = SiteSettings.DashboardParts? + .FirstOrDefault(o => o.Id == context.Forms.Int("DashboardPartId")); + if (dashboardPart != null) + { + dashboardPart.View = new View(); + } + res + .Html( + "#DashboardPartViewFiltersTabContainer", + new HtmlBuilder() + .ViewFiltersTab( + context: context, + ss: currentSs, + view: new View(), + prefix: "DashboardPart", + currentTableOnly: true)) + .Html( + target: "#DashboardPartKambanValue", + value: new HtmlBuilder() + .OptionCollection( + context: context, + optionCollection: currentSs.KambanValueOptions(context: context)?.ToDictionary( + o => o.Key, o => new ControlData(o.Value)), + selectedValue: currentSs.ReferenceType == "Issues" ? "RemainingWorkValue" : "NumA")); + } + /// /// Fixed: /// @@ -8661,5 +8952,162 @@ private void ChangeFormulaCalculationMethod(Context context, ResponseCollection .ToJson(); } } + + /// + /// Fixed: + /// + private List ParsePermissions(ApiSiteSettingPermission apiSettingPermission, SiteSettings ss, object target = null) + { + var permissions = new List(); + if (apiSettingPermission == null) { + return permissions; + } + apiSettingPermission.Users?.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "User", + id: id))); + apiSettingPermission.Groups?.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "Group", + id: id))); + apiSettingPermission.Depts?.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "Dept", + id: id))); + switch (target) + { + case Process process when target.GetType().Name == nameof(Process): + if (process.Users != null && apiSettingPermission.Users == null) { + process.Users.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "User", + id: id))); + } + if (process.Depts != null && apiSettingPermission.Depts == null) + { + process.Depts.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "Dept", + id: id))); + } + if (process.Groups != null && apiSettingPermission.Groups == null) + { + process.Groups.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "Group", + id: id))); + } + break; + case StatusControl statusControll when target.GetType().Name == nameof(StatusControl): + if (statusControll.Users != null && apiSettingPermission.Users == null) + { + statusControll.Users.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "User", + id: id))); + } + if (statusControll.Depts != null && apiSettingPermission.Depts == null) + { + statusControll.Depts.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "Dept", + id: id))); + } + if (statusControll.Groups != null && apiSettingPermission.Groups == null) + { + statusControll.Groups.ForEach(id => permissions.Add(new Permission( + ss: ss, + name: "Group", + id: id))); + } + break; + } + return permissions; + } + + /// + /// Fixed: + /// + private SettingList ParseValidateInputs(SettingList validateInputs, Process process) + { + var data = new SettingList(); + if (validateInputs == null) { + return null; + } + validateInputs.ForEach(o => { + if (o.Delete != 1) + { + data.Add(o); + } + }); + if (process?.ValidateInputs != null) { + var requestIds = validateInputs.Select(o => o.Id).ToArray(); + process.ValidateInputs.ForEach(o => { + if (!requestIds.Contains(o.Id)) + { + data.Add(o); + } + }); + } + return data; + } + + /// + /// Fixed: + /// + private SettingList ParseDataChanges(SettingList dataChanges, Process process) + { + var data = new SettingList(); + if (dataChanges == null) + { + return null; + } + dataChanges.ForEach(o => { + if (o.Delete != 1) + { + data.Add(o); + } + }); + if (process?.DataChanges != null) + { + var requestIds = dataChanges.Select(o => o.Id).ToArray(); + process.DataChanges.ForEach(o => { + if (!requestIds.Contains(o.Id)) + { + data.Add(o); + } + }); + } + return data; + } + + /// + /// Fixed: + /// + private SettingList ParseNotifications(SettingList notifications, Process process) + { + var data = new SettingList(); + if (notifications == null) + { + return null; + } + notifications.ForEach(o => { + if (o.Delete != 1) + { + data.Add(o); + } + }); + if (process?.Notifications != null) + { + var requestIds = notifications.Select(o => o.Id).ToArray(); + process.Notifications.ForEach(o => { + if (!requestIds.Contains(o.Id)) + { + data.Add(o); + } + }); + } + return data; + } } } diff --git a/Implem.Pleasanter/Models/Sites/SiteUtilities.cs b/Implem.Pleasanter/Models/Sites/SiteUtilities.cs index 65b26f9b2..2fe56c66c 100644 --- a/Implem.Pleasanter/Models/Sites/SiteUtilities.cs +++ b/Implem.Pleasanter/Models/Sites/SiteUtilities.cs @@ -2353,7 +2353,8 @@ public static ContentResultInheritance UpdateSiteSettingsByApi( var apiSiteSettingValidator = ApiSiteSettingValidators.OnChageSiteSettingByApi( referenceType: siteModel.ReferenceType, ss: ss, - siteSettingsModel: siteSettingsApiModel); + siteSettingsModel: siteSettingsApiModel, + context: context); switch (apiSiteSettingValidator.Type) { case Error.Types.None: break; @@ -2387,6 +2388,20 @@ public static ContentResultInheritance UpdateSiteSettingsByApi( siteSetting: ss, htmlsApiSiteSetting: siteSettingsApiModel.Htmls); } + if (siteSettingsApiModel.Processes != null) + { + siteModel.UpsertProcessByApi( + siteSetting: ss, + processesApiSiteSetting: siteSettingsApiModel.Processes, + context: context); + } + if (siteSettingsApiModel.StatusControls != null) + { + siteModel.UpsertStatusControlByApi( + siteSetting: ss, + statusControlSettings: siteSettingsApiModel.StatusControls, + context: context); + } var errorData = siteModel.Update( context: context, ss: ss); @@ -4539,6 +4554,11 @@ private static HtmlBuilder Editor( .Id("DashboardPartCalendarSitesDialog") .Class("dialog") .Title(Displays.SiteId(context: context))) + .Div( + attributes: new HtmlAttributes() + .Id("DashboardPartKambanSitesDialog") + .Class("dialog") + .Title(Displays.SiteId(context: context))) .Div( attributes: new HtmlAttributes() .Id("ServerScriptDialog") @@ -11202,7 +11222,16 @@ private static HtmlBuilder ViewCalendarTab( fieldCss: "field-auto-thin", labelText: Displays.Period(context: context), optionCollection: ss.CalendarTimePeriodOptions(context: context), - selectedValue: view.GetCalendarTimePeriod(ss: ss)) + selectedValue: view.GetCalendarTimePeriod(ss: ss), + _using: ss.CalendarType == SiteSettings.CalendarTypes.Standard) + .FieldDropDown( + context: context, + controlId: "CalendarViewType", + fieldCss: "field-auto-thin", + labelText: Displays.Period(context: context), + optionCollection: ss.CalendarViewTypeOptions(context: context), + selectedValue: view.GetCalendarViewType(), + _using: ss.CalendarType == SiteSettings.CalendarTypes.FullCalendar) .FieldDropDown( context: context, controlId: "CalendarFromTo", @@ -14048,7 +14077,7 @@ public static HtmlBuilder ScriptDialog( labelText: Displays.Script(context: context), text: script.Body) .FieldCheckBox( - fieldId: "ScriptDisabled", + fieldId: "ScriptDisabledField", controlId: "ScriptDisabled", controlCss: " always-send", labelText: Displays.Disabled(context: context), @@ -15423,6 +15452,56 @@ public static HtmlBuilder DashboardPartCalendarSitesDialog( method: "post"))); } + /// + /// Fixed: + /// + public static HtmlBuilder DashboardPartKambanSitesDialog( + Context context, + SiteSettings ss, + int dashboardPartId, + string dashboardKambanSites) + { + var hb = new HtmlBuilder(); + return hb.Form( + attributes: new HtmlAttributes() + .Id("DashboardPartKambanSitesEditForm") + .Action(Locations.ItemAction( + context: context, + id: ss.SiteId)), + action: () => hb + .FieldTextBox( + controlId: "DashboardPartKambanSitesEdit", + fieldCss: "field-wide", + controlCss: " always-send", + labelText: Displays.SiteId(context: context), + text: dashboardKambanSites, + validateRequired: true) + .Hidden( + controlId: "DashboardPartId", + alwaysSend: true, + value: dashboardPartId.ToString()) + .Hidden( + controlId: "SavedDashboardPartKambanSites", + alwaysSend: true, + value: dashboardKambanSites) + .Hidden( + controlId: "ClearDashboardKambanView", + action: "SetSiteSettings", + method: "post") + .P( + id: "DashboardPartKambanSitesMessage", + css: "message-dialog") + .Div(css: "command-center", action: () => hb + .Button( + controlId: "UpdateDashboardPartKambanSites", + text: Displays.OK(context: context), + controlCss: "button-icon validate", + icon: "ui-icon-pencil", + onClick: "$p.send($(this));", + action: "SetSiteSettings", + method: "post"))); + } + /// /// Fixed: /// @@ -15434,7 +15513,9 @@ public static HtmlBuilder DashboardPartDialog( { var filterVisible = false; var sorterVisible = false; - if((dashboardPart.Type == DashboardPartType.TimeLine) || (dashboardPart.Type == DashboardPartType.Calendar)) + if((dashboardPart.Type == DashboardPartType.TimeLine) + || (dashboardPart.Type == DashboardPartType.Calendar) + || (dashboardPart.Type == DashboardPartType.Kamban)) { filterVisible = true; } @@ -15581,6 +15662,10 @@ private static HtmlBuilder DashboardPartGeneralTab( { DashboardPartType.Calendar.ToInt().ToString(), Displays.Calendar(context: context) + }, + { + DashboardPartType.Kamban.ToInt().ToString(), + Displays.Kamban(context: context) } }, selectedValue: dashboardPart.Type.ToInt().ToString(), @@ -15822,6 +15907,114 @@ private static HtmlBuilder DashboardPartGeneralTab( fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Calendar), labelText: Displays.ShowStatus(context: context), _checked: dashboardPart.CalendarShowStatus == true) + .Div( + id: "DashboardPartKambanSitesField", + css: "both" + hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + action: () => + { + var kambanSites = dashboardPart.KambanSites; + var baseSiteId = DashboardPart.GetBaseSiteSettings( + context: context, + sitesString: kambanSites) + ?.SiteId; + hb + .FieldText( + controlId: "DashboardPartKambanSitesValue", + labelText: Displays.SiteId(context: context), + text: kambanSites) + .Hidden( + controlId: "DashboardPartKambanSites", + alwaysSend: true, + value: kambanSites) + .Hidden( + controlId: "DashboardPartKambanBaseSiteId", + alwaysSend: true, + value: baseSiteId == null + ? null + : baseSiteId.ToString()) + .Button( + controlId: "EditKambanSites", + text: Displays.Edit(context: context), + controlCss: "button-icon", + onClick: "$p.openDashboardPartKambanSitesDialog($(this));", + icon: "ui-icon-pencil", + action: "SetSiteSettings", + method: "post"); + }) + .FieldDropDown( + context: context, + controlId: "DashboardPartKambanGroupByX", + fieldId: "DashboardPartKambanGroupByXField", + fieldCss: "both field-normal" + hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + controlCss: " always-send", + labelText: Displays.GroupByX(context: context), + optionCollection: ss.KambanGroupByOptions(context: context), + selectedValue: !dashboardPart.KambanGroupByX.IsNullOrEmpty() + ? dashboardPart.KambanGroupByX + : "Status") + .FieldDropDown( + context: context, + controlId: "DashboardPartKambanGroupByY", + fieldId: "DashboardPartKambanGroupByYField", + fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + controlCss: " always-send", + labelText: Displays.GroupByY(context: context), + optionCollection: ss.KambanGroupByOptions( + context: context, + addNothing: true), + selectedValue: !dashboardPart.KambanGroupByX.IsNullOrEmpty() + ? dashboardPart.KambanGroupByY + : "Owner") + .FieldDropDown( + context: context, + controlId: "DashboardPartKambanAggregateType", + fieldId: "DashboardPartKambanAggregateTypeField", + fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + controlCss: " always-send", + labelText: Displays.AggregationType(context: context), + optionCollection: ss.KambanAggregationTypeOptions(context: context), + selectedValue: !dashboardPart.KambanAggregateType.IsNullOrEmpty() + ? dashboardPart.KambanAggregateType + : "Total") + .FieldDropDown( + context: context, + controlId: "DashboardPartKambanValue", + fieldId: "DashboardPartKambanValueField", + fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Kamban || dashboardPart.KambanAggregateType == "Count"), + controlCss: " always-send", + labelText: Displays.AggregationTarget(context: context), + optionCollection: ss.KambanValueOptions(context: context), + selectedValue: !dashboardPart.KambanValue.IsNullOrEmpty() + ? dashboardPart.KambanValue + : ss.ReferenceType == "Issues" ? "RemainingWorkValue" : "NumA") + .FieldDropDown( + context: context, + controlId: "DashboardPartKambanColumns", + fieldId: "DashboardPartKambanColumnsField", + fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + controlCss: " always-send", + labelText: Displays.MaxColumns(context: context), + optionCollection: Enumerable.Range( + Parameters.General.KambanMinColumns, + Parameters.General.KambanMaxColumns - Parameters.General.KambanMinColumns + 1) + .ToDictionary(o => o.ToString(), o => o.ToString()), + selectedValue: !dashboardPart.KambanColumns.IsNullOrEmpty() + ? dashboardPart.KambanColumns + : "10") + .FieldCheckBox( + controlId: "DashboardPartKambanAggregationView", + fieldId: "DashboardPartKambanAggregationViewField", + fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + controlCss: " always-send", + labelText: Displays.AggregationView(context: context), + _checked: dashboardPart.KambanAggregationView == true) + .FieldCheckBox( + controlId: "DashboardPartKambanShowStatus", + fieldId: "DashboardPartKambanShowStatusField", + fieldCss: hiddenCss(dashboardPart.Type != DashboardPartType.Kamban), + controlCss: " always-send", + labelText: Displays.ShowStatus(context: context), + _checked: dashboardPart.KambanShowStatus == true) .FieldCheckBox( controlId: "DisableAsynchronousLoading", controlCss: " always-send", diff --git a/Implem.Pleasanter/Models/Sites/SiteValidators.cs b/Implem.Pleasanter/Models/Sites/SiteValidators.cs index eed06cbec..bd6eab3ac 100644 --- a/Implem.Pleasanter/Models/Sites/SiteValidators.cs +++ b/Implem.Pleasanter/Models/Sites/SiteValidators.cs @@ -418,7 +418,7 @@ public static ErrorData InheritPermission(Context context, SiteSettings ss) { if (!PermissionUtilities.InheritTargetsDataRows( context: context, - ss: ss).Any(o => + ss: ss).DataRows.Any(o => o.Long("SiteId") == context.Forms.Long("InheritPermission"))) { return new ErrorData(type: Error.Types.CanNotInherit); diff --git a/Implem.Pleasanter/Models/SysLogs/SysLogApiModel.cs b/Implem.Pleasanter/Models/SysLogs/SysLogApiModel.cs index 8961ce231..3680e23fc 100644 --- a/Implem.Pleasanter/Models/SysLogs/SysLogApiModel.cs +++ b/Implem.Pleasanter/Models/SysLogs/SysLogApiModel.cs @@ -22,7 +22,7 @@ public class SysLogApiModel : _BaseApiModel public long? ReferenceId { get; set; } public string ReferenceType { get; set; } public long? Status { get; set; } - public string Description { get; set; } + public new string Description { get; set; } public string RequestData { get; set; } public string HttpMethod { get; set; } public int? RequestSize { get; set; } diff --git a/Implem.Pleasanter/Models/Tenants/TenantUtilities.cs b/Implem.Pleasanter/Models/Tenants/TenantUtilities.cs index 6be5004fb..b93ca392c 100644 --- a/Implem.Pleasanter/Models/Tenants/TenantUtilities.cs +++ b/Implem.Pleasanter/Models/Tenants/TenantUtilities.cs @@ -2564,6 +2564,20 @@ private static Dictionary ExecutingUsersOptionCollection( context: context, siteId: context.SiteId, searchIndexes: searchIndexes?.ToList()); + if (!selected.All(o => column.ChoiceHash.ContainsKey(o))) + { + selected + .Select(userId => SiteInfo.User( + context: context, + userId: userId.ToInt())) + .Where(o => !o.Anonymous()) + .ForEach(user => + column.ChoiceHash.AddIfNotConainsKey( + user.Id.ToString(), + new Choice( + value: user.Id.ToString(), + text: user.Name))); + } var optionCollection = column?.EditChoices( context: context, addNotSet: true, diff --git a/Implem.Pleasanter/Models/Users/UserUtilities.cs b/Implem.Pleasanter/Models/Users/UserUtilities.cs index 0d22ac8b5..dd83d6ef8 100644 --- a/Implem.Pleasanter/Models/Users/UserUtilities.cs +++ b/Implem.Pleasanter/Models/Users/UserUtilities.cs @@ -5447,5 +5447,16 @@ private static int PhysicalBulkDelete( }).Count.ToInt(); return count; } + + public static int CountByIds(Context context, SiteSettings ss, List ids) + { + return Repository.ExecuteScalar_int( + context: context, + statements: Rds.SelectUsers( + column: Rds.UsersColumn() + .UsersCount(), + where: Rds.UsersWhere() + .UserId_In(value: ids))); + } } } diff --git a/Implem.Pleasanter/Models/Wikis/WikiModel.cs b/Implem.Pleasanter/Models/Wikis/WikiModel.cs index 2877fe2f6..4f9a9ee67 100644 --- a/Implem.Pleasanter/Models/Wikis/WikiModel.cs +++ b/Implem.Pleasanter/Models/Wikis/WikiModel.cs @@ -1491,40 +1491,45 @@ public void SetByFormula(Context context, SiteSettings ss) ss: ss, formulaScript: formulaSet.FormulaScript, calculationMethod: formulaSet.CalculationMethod); - try + var value = FormulaServerScriptUtilities.Execute( + context: context, + ss: ss, + itemModel: this, + formulaScript: formulaSet.FormulaScript); + switch (value) { - var value = FormulaServerScriptUtilities.Execute( - context: context, - ss: ss, - itemModel: this, - formulaScript: formulaSet.FormulaScript); - var formData = new Dictionary - { - { $"Wikis_{columnName}", value.ToString() } - }; - SetByFormData( - context: context, - ss: ss, - formData: formData); - if (ss.OutputFormulaLogs == true) - { - context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); - context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); - context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); - } + case "#N/A": + case "#VALUE!": + case "#REF!": + case "#DIV/0!": + case "#NUM!": + case "#NAME?": + case "#NULL!": + case "Invalid Parameter": + if (formulaSet.IsDisplayError == true) + { + throw new Exception($"Formula error {value}"); + } + new SysLogModel( + context: context, + method: nameof(SetByFormula), + message: $"Formula error {value}", + sysLogType: SysLogModel.SysLogTypes.Execption); + break; } - catch (Exception exception) + var formData = new Dictionary { - if (formulaSet.IsDisplayError == true) - { - throw new Exception($"Formula error {exception.Message}"); - } - new SysLogModel( - context: context, - method: nameof(SetByFormula), - message: $"Formula error {exception.Message}", - errStackTrace: exception.StackTrace, - sysLogType: SysLogModel.SysLogTypes.Execption); + { $"Wikis_{columnName}", value.ToString() } + }; + SetByFormData( + context: context, + ss: ss, + formData: formData); + if (ss.OutputFormulaLogs == true) + { + context.LogBuilder?.AppendLine($"formulaSet: {formulaSet.GetRecordingData().ToJson()}"); + context.LogBuilder?.AppendLine($"formulaSource: {this.ToJson()}"); + context.LogBuilder?.AppendLine($"formulaResult: {{\"{columnName}\":{value}}}"); } } }); diff --git a/Implem.Pleasanter/Startup.cs b/Implem.Pleasanter/Startup.cs index ac9c1c9ea..a1074d923 100644 --- a/Implem.Pleasanter/Startup.cs +++ b/Implem.Pleasanter/Startup.cs @@ -515,9 +515,9 @@ public SecurityHeadersMiddleware(RequestDelegate next) } public Task Invoke(HttpContext context) { - context.Response.Headers.Add("X-Frame-Options", new StringValues("SAMEORIGIN")); - context.Response.Headers.Add("X-Xss-Protection", new StringValues("1; mode=block")); - context.Response.Headers.Add("X-Content-Type-Options", new StringValues("nosniff")); + context.Response.Headers.Append("X-Frame-Options", new StringValues("SAMEORIGIN")); + context.Response.Headers.Append("X-Xss-Protection", new StringValues("1; mode=block")); + context.Response.Headers.Append("X-Content-Type-Options", new StringValues("nosniff")); if (Parameters.Security.SecureCacheControl != null) { if (Parameters.Security.SecureCacheControl.NoCache @@ -536,7 +536,7 @@ public Task Invoke(HttpContext context) } if (Parameters.Security.SecureCacheControl.PragmaNoCache) { - context.Response.Headers.Add("Pragma", new StringValues("no-cache")); + context.Response.Headers.Append("Pragma", new StringValues("no-cache")); } } return _next(context); diff --git a/Implem.Pleasanter/wwwroot/content/styles.css b/Implem.Pleasanter/wwwroot/content/styles.css index 1a454fe7b..a7894d781 100644 --- a/Implem.Pleasanter/wwwroot/content/styles.css +++ b/Implem.Pleasanter/wwwroot/content/styles.css @@ -653,7 +653,7 @@ pre { table-layout: fixed; } -.CalendarBody thead th { +div.Calendar > .CalendarBody > .grid > thead > tr > th { padding: 5px; text-align: center; border: solid 1px silver; @@ -986,23 +986,27 @@ th.calendar-header { fill: black; } -#KambanBody .kamban-row { +.kambanbody .kamban-row { border-bottom: dotted 1px silver; } -#KambanBody .kamban-container > div { +.kambanbody .kamban-container{ + background-color: white; +} + +.kambanbody .kamban-container > div { min-height: 30px; } -#KambanBody .kamban-container.hover { +.kambanbody .kamban-container.hover { background-color: whitesmoke; } -#KambanBody .kamban-container .kamban-item:last-child { +.kambanbody .kamban-container .kamban-item:last-child { margin: 3px 3px 30px 3px; } -#KambanBody .kamban-item { +.kambanbody .kamban-item { margin: 3px; padding: 4px 16px 4px 5px; background-color: lightgoldenrodyellow; @@ -1010,39 +1014,56 @@ th.calendar-header { position: relative; cursor: pointer; border-radius: 5px; + overflow: hidden; } - #KambanBody .kamban-item:hover { + .kambanbody .kamban-item:hover { background-color: white; border: solid 1px orange; } - #KambanBody .kamban-item.changed { + .kambanbody .kamban-item.changed { font-weight: bold; background-color: yellow; border: solid 1px orange; } - #KambanBody .kamban-item .ui-icon { + .kambanbody .kamban-item .ui-icon { position: absolute; top: 0px; right: 0px; } - #KambanBody .kamban-item > span { + .kambanbody .kamban-item > span { margin-right: 3px; } -#ImageLib .item { - width: 250px; - height: 250px; - float: left; - margin: 10px 10px 0px 0px; - padding: 10px; - border: solid 1px silver; - position: relative; - overflow: hidden; + .kambanbody .dragging { + padding: 5px; + background-color: lightgoldenrodyellow; + border-radius: 3px; + z-index: 50; + } + +.dashboard-kamban-header { + position: sticky; + top: -20px; + z-index: 1; } + .dashboard-kamban-header > th { + overflow-x: hidden; + } + + #ImageLib .item { + width: 250px; + height: 250px; + float: left; + margin: 10px 10px 0px 0px; + padding: 10px; + border: solid 1px silver; + position: relative; + overflow: hidden; + } #ImageLib .item .image { width: 100%; diff --git a/Implem.Pleasanter/wwwroot/content/styles.min.css b/Implem.Pleasanter/wwwroot/content/styles.min.css index 3a1e93594..5461e3eee 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,Hiragino Kaku Gothic Pro;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 .item .title>span:not(.ui-icon){margin-right:3px}.CalendarBody .dragging{height:25px;padding:5px;background-color:#fafad2;border-radius:3px;z-index:50}.CalendarBody .dummy{height:25px;margin:5px 0 0 0}.fc .fc-scrollgrid-section-sticky>*{z-index:2}#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}#KambanBody .kamban-item>span{margin-right:3px}#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>h3>a>span{font-weight:bold}#SearchResults .result>p{display:block;float:left;clear:both}#SearchResults .result:hover{border:solid 1px #ffa500;cursor:pointer}.highlight{background:#ff0}#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:100}#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:100}#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.dashboards{box-shadow:4px 4px 2px rgba(0,0,0,.2)}.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}.container-radio>label.error{top:0}.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,Hiragino Kaku Gothic Pro;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 6px}.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}.container-radio{padding:7px 0}.container-radio>label{display:block;float:left;margin:0 5px 0 0;white-space:nowrap}.control-radio{display:block;float:left;margin:3px}.radio-clear-both .container-radio>label{clear:both}.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}.show-password{position:absolute;top:4px;right:-27px;cursor:pointer;z-index:10}input[type="password"]::-ms-reveal{display:none}.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,Hiragino Kaku Gothic Pro}.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}.annonymous .close-announcement{display:none}.grid-stack{background-color:#fff;margin:10px}.grid-stack-item-content{background-color:#f5f5f5}.dashboard-timeline-container{display:flex;flex-direction:column;gap:4px}.dashboard-timeline-item{background-color:#fff;margin:4px;padding:8px;transition:background-color .3s;cursor:pointer;box-shadow:0 2px 4px rgba(0,0,0,.2);border-radius:4px}.dashboard-timeline-item:hover{background-color:#ebebeb}.dashboard-timeline-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.dashboard-timeline-header a{color:#007bff;font-weight:bold;min-width:40px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dashboard-timeline-header-closed{overflow:hidden;max-height:0;margin-bottom:0}.dashboard-timeline-item:hover .dashboard-timeline-header-closed{max-height:200px;margin-bottom:4px;overflow:auto;transition:max-height .5s linear 1s}.dashboard-timeline-record-time{font-size:.8em;color:#777;margin-left:3px;font-weight:bold;display:flex;white-space:nowrap}.dashboard-timeline-record-time time{margin-left:4px}.dashboard-timeline-record-time .elapsed-time{margin-left:4px;font-weight:bold;background-color:#eee}.dashboard-timeline-title{font-size:1.2em;font-weight:bold;color:#333}.dashboard-timeline-body{margin-top:8px;line-height:1.5;color:#555}.dashboard-timeline-body-closed{margin-top:0;overflow:hidden;max-height:0}.dashboard-timeline-item:hover .dashboard-timeline-body-closed{margin-top:8px;max-height:300px;overflow:auto;transition:max-height .5s linear 1s,margin-top 0s;transition-delay:1s}.grid-stack-item-content{background-color:#f2f2f2;padding:16px;border-radius:5px;box-shadow:0 2px 4px rgba(0,0,0,.1);display:flex;flex-direction:column}.dashboard-part-title{font-size:1.2em;color:#333;font-weight:bold;margin-bottom:10px}.dashboard-part-nav{margin-top:10px}.dashboard-part-nav-menu{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap}.dashboard-part-nav-menu>.dashboard-part-nav-item{max-width:200px;min-width:120px;margin-left:10px;white-space:nowrap;overflow:hidden;padding:4px;box-shadow:0 2px 4px rgba(0,0,0,.2)}.dashboard-part-nav-menu-vartical{list-style:none;padding:0;margin:0;display:flex;flex-direction:column}.dashboard-part-nav-item{color:#333;margin-bottom:8px;padding:4px;display:flex;border-radius:4px;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.2)}.dashboard-part-nav-item:hover{background-color:#ddd}.dashboard-part-nav-link{padding:4px;text-decoration:none;color:inherit;width:100%}.dashboard-part-refresh{position:absolute;top:8px;left:8px;border:none;color:#636363;background-color:transparent;opacity:0;padding-top:0;padding-left:0;z-index:5}@keyframes custom-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.dashboard-part-road{position:absolute;left:calc(50% - 25px);top:calc(50% - 25px);font-size:50px;color:#636363;display:inline-block;animation:custom-spin 1s linear infinite}.gs-20>.grid-stack-item{width:5%;min-width:5%}.gs-20>.grid-stack-item[gs-w="1"]{width:5%;min-width:5%}.gs-20>.grid-stack-item[gs-x="1"]{left:5%}.gs-20>.grid-stack-item[gs-w="2"]{width:10%}.gs-20>.grid-stack-item[gs-x="2"]{left:10%}.gs-20>.grid-stack-item[gs-w="3"]{width:15%}.gs-20>.grid-stack-item[gs-x="3"]{left:15%}.gs-20>.grid-stack-item[gs-w="4"]{width:20%}.gs-20>.grid-stack-item[gs-x="4"]{left:20%}.gs-20>.grid-stack-item[gs-w="5"]{width:25%}.gs-20>.grid-stack-item[gs-x="5"]{left:25%}.gs-20>.grid-stack-item[gs-w="6"]{width:30%}.gs-20>.grid-stack-item[gs-x="6"]{left:30%}.gs-20>.grid-stack-item[gs-w="7"]{width:35%}.gs-20>.grid-stack-item[gs-x="7"]{left:35%}.gs-20>.grid-stack-item[gs-w="8"]{width:40%}.gs-20>.grid-stack-item[gs-x="8"]{left:40%}.gs-20>.grid-stack-item[gs-w="9"]{width:45%}.gs-20>.grid-stack-item[gs-x="9"]{left:45%}.gs-20>.grid-stack-item[gs-w="10"]{width:50%}.gs-20>.grid-stack-item[gs-x="10"]{left:50%}.gs-20>.grid-stack-item[gs-w="11"]{width:55%}.gs-20>.grid-stack-item[gs-x="11"]{left:55%}.gs-20>.grid-stack-item[gs-w="12"]{width:60%}.gs-20>.grid-stack-item[gs-x="12"]{left:60%}.gs-20>.grid-stack-item[gs-w="13"]{width:65%}.gs-20>.grid-stack-item[gs-x="13"]{left:65%}.gs-20>.grid-stack-item[gs-w="14"]{width:70%}.gs-20>.grid-stack-item[gs-x="14"]{left:70%}.gs-20>.grid-stack-item[gs-w="15"]{width:75%}.gs-20>.grid-stack-item[gs-x="15"]{left:75%}.gs-20>.grid-stack-item[gs-w="16"]{width:80%}.gs-20>.grid-stack-item[gs-x="16"]{left:80%}.gs-20>.grid-stack-item[gs-w="17"]{width:85%}.gs-20>.grid-stack-item[gs-x="17"]{left:85%}.gs-20>.grid-stack-item[gs-w="18"]{width:90%}.gs-20>.grid-stack-item[gs-x="18"]{left:90%}.gs-20>.grid-stack-item[gs-w="19"]{width:95%}.gs-20>.grid-stack-item[gs-x="19"]{left:95%}.gs-20>.grid-stack-item[gs-w="20"]{width:100%} \ 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,Hiragino Kaku Gothic Pro;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}div.Calendar>.CalendarBody>.grid>thead>tr>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 .item .title>span:not(.ui-icon){margin-right:3px}.CalendarBody .dragging{height:25px;padding:5px;background-color:#fafad2;border-radius:3px;z-index:50}.CalendarBody .dummy{height:25px;margin:5px 0 0 0}.fc .fc-scrollgrid-section-sticky>*{z-index:2}#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{background-color:#fff}.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;overflow:hidden}.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}.kambanbody .kamban-item>span{margin-right:3px}.kambanbody .dragging{padding:5px;background-color:#fafad2;border-radius:3px;z-index:50}.dashboard-kamban-header{position:sticky;top:-20px;z-index:1}.dashboard-kamban-header>th{overflow-x:hidden}#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>h3>a>span{font-weight:bold}#SearchResults .result>p{display:block;float:left;clear:both}#SearchResults .result:hover{border:solid 1px #ffa500;cursor:pointer}.highlight{background:#ff0}#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:100}#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:100}#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.dashboards{box-shadow:4px 4px 2px rgba(0,0,0,.2)}.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}.container-radio>label.error{top:0}.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,Hiragino Kaku Gothic Pro;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 6px}.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}.container-radio{padding:7px 0}.container-radio>label{display:block;float:left;margin:0 5px 0 0;white-space:nowrap}.control-radio{display:block;float:left;margin:3px}.radio-clear-both .container-radio>label{clear:both}.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}.show-password{position:absolute;top:4px;right:-27px;cursor:pointer;z-index:10}input[type="password"]::-ms-reveal{display:none}.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,Hiragino Kaku Gothic Pro}.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}.annonymous .close-announcement{display:none}.grid-stack{background-color:#fff;margin:10px}.grid-stack-item-content{background-color:#f5f5f5}.dashboard-timeline-container{display:flex;flex-direction:column;gap:4px}.dashboard-timeline-item{background-color:#fff;margin:4px;padding:8px;transition:background-color .3s;cursor:pointer;box-shadow:0 2px 4px rgba(0,0,0,.2);border-radius:4px}.dashboard-timeline-item:hover{background-color:#ebebeb}.dashboard-timeline-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}.dashboard-timeline-header a{color:#007bff;font-weight:bold;min-width:40px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.dashboard-timeline-header-closed{overflow:hidden;max-height:0;margin-bottom:0}.dashboard-timeline-item:hover .dashboard-timeline-header-closed{max-height:200px;margin-bottom:4px;overflow:auto;transition:max-height .5s linear 1s}.dashboard-timeline-record-time{font-size:.8em;color:#777;margin-left:3px;font-weight:bold;display:flex;white-space:nowrap}.dashboard-timeline-record-time time{margin-left:4px}.dashboard-timeline-record-time .elapsed-time{margin-left:4px;font-weight:bold;background-color:#eee}.dashboard-timeline-title{font-size:1.2em;font-weight:bold;color:#333}.dashboard-timeline-body{margin-top:8px;line-height:1.5;color:#555}.dashboard-timeline-body-closed{margin-top:0;overflow:hidden;max-height:0}.dashboard-timeline-item:hover .dashboard-timeline-body-closed{margin-top:8px;max-height:300px;overflow:auto;transition:max-height .5s linear 1s,margin-top 0s;transition-delay:1s}.grid-stack-item-content{background-color:#f2f2f2;padding:16px;border-radius:5px;box-shadow:0 2px 4px rgba(0,0,0,.1);display:flex;flex-direction:column}.dashboard-part-title{font-size:1.2em;color:#333;font-weight:bold;margin-bottom:10px}.dashboard-part-nav{margin-top:10px}.dashboard-part-nav-menu{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap}.dashboard-part-nav-menu>.dashboard-part-nav-item{max-width:200px;min-width:120px;margin-left:10px;white-space:nowrap;overflow:hidden;padding:4px;box-shadow:0 2px 4px rgba(0,0,0,.2)}.dashboard-part-nav-menu-vartical{list-style:none;padding:0;margin:0;display:flex;flex-direction:column}.dashboard-part-nav-item{color:#333;margin-bottom:8px;padding:4px;display:flex;border-radius:4px;background-color:#fff;box-shadow:0 2px 4px rgba(0,0,0,.2)}.dashboard-part-nav-item:hover{background-color:#ddd}.dashboard-part-nav-link{padding:4px;text-decoration:none;color:inherit;width:100%}.dashboard-part-refresh{position:absolute;top:8px;left:8px;border:none;color:#636363;background-color:transparent;opacity:0;padding-top:0;padding-left:0;z-index:5}@keyframes custom-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}.dashboard-part-road{position:absolute;left:calc(50% - 25px);top:calc(50% - 25px);font-size:50px;color:#636363;display:inline-block;animation:custom-spin 1s linear infinite}.gs-20>.grid-stack-item{width:5%;min-width:5%}.gs-20>.grid-stack-item[gs-w="1"]{width:5%;min-width:5%}.gs-20>.grid-stack-item[gs-x="1"]{left:5%}.gs-20>.grid-stack-item[gs-w="2"]{width:10%}.gs-20>.grid-stack-item[gs-x="2"]{left:10%}.gs-20>.grid-stack-item[gs-w="3"]{width:15%}.gs-20>.grid-stack-item[gs-x="3"]{left:15%}.gs-20>.grid-stack-item[gs-w="4"]{width:20%}.gs-20>.grid-stack-item[gs-x="4"]{left:20%}.gs-20>.grid-stack-item[gs-w="5"]{width:25%}.gs-20>.grid-stack-item[gs-x="5"]{left:25%}.gs-20>.grid-stack-item[gs-w="6"]{width:30%}.gs-20>.grid-stack-item[gs-x="6"]{left:30%}.gs-20>.grid-stack-item[gs-w="7"]{width:35%}.gs-20>.grid-stack-item[gs-x="7"]{left:35%}.gs-20>.grid-stack-item[gs-w="8"]{width:40%}.gs-20>.grid-stack-item[gs-x="8"]{left:40%}.gs-20>.grid-stack-item[gs-w="9"]{width:45%}.gs-20>.grid-stack-item[gs-x="9"]{left:45%}.gs-20>.grid-stack-item[gs-w="10"]{width:50%}.gs-20>.grid-stack-item[gs-x="10"]{left:50%}.gs-20>.grid-stack-item[gs-w="11"]{width:55%}.gs-20>.grid-stack-item[gs-x="11"]{left:55%}.gs-20>.grid-stack-item[gs-w="12"]{width:60%}.gs-20>.grid-stack-item[gs-x="12"]{left:60%}.gs-20>.grid-stack-item[gs-w="13"]{width:65%}.gs-20>.grid-stack-item[gs-x="13"]{left:65%}.gs-20>.grid-stack-item[gs-w="14"]{width:70%}.gs-20>.grid-stack-item[gs-x="14"]{left:70%}.gs-20>.grid-stack-item[gs-w="15"]{width:75%}.gs-20>.grid-stack-item[gs-x="15"]{left:75%}.gs-20>.grid-stack-item[gs-w="16"]{width:80%}.gs-20>.grid-stack-item[gs-x="16"]{left:80%}.gs-20>.grid-stack-item[gs-w="17"]{width:85%}.gs-20>.grid-stack-item[gs-x="17"]{left:85%}.gs-20>.grid-stack-item[gs-w="18"]{width:90%}.gs-20>.grid-stack-item[gs-x="18"]{left:90%}.gs-20>.grid-stack-item[gs-w="19"]{width:95%}.gs-20>.grid-stack-item[gs-x="19"]{left:95%}.gs-20>.grid-stack-item[gs-w="20"]{width:100%} \ No newline at end of file diff --git a/Implem.Pleasanter/wwwroot/scripts/calendar.js b/Implem.Pleasanter/wwwroot/scripts/calendar.js index a10dbf785..c0d64f34a 100644 --- a/Implem.Pleasanter/wwwroot/scripts/calendar.js +++ b/Implem.Pleasanter/wwwroot/scripts/calendar.js @@ -105,36 +105,37 @@ const getEventsDatas = function (calendarSuffix) { $p.send($control); } else { $('#IsInit' + calendarSuffix).val('False'); - let eventData = JSON.parse($('#CalendarJson' + calendarSuffix).val())[0]['items']; - successCallback( - eventData.map((item) => { - var endDate = new Date(item.end); - if ($('#CalendarEditorFormat' + calendarSuffix).val() === 'Ymd') { - endDate.setDate(endDate.getDate() + 1); - } - if (item.StatusHtml) { - return { - id: item.id, - title: item.title, - start: item.start, - end: endDate, - StatusHtml: item.StatusHtml, - siteId: item.siteId + if (JSON.parse($('#CalendarJson' + calendarSuffix).val()).length !== 0) { + let eventData = JSON.parse($('#CalendarJson' + calendarSuffix).val())[0]['items']; + successCallback( + eventData.map((item) => { + var endDate = new Date(item.end); + if ($('#CalendarEditorFormat' + calendarSuffix).val() === 'Ymd') { + endDate.setDate(endDate.getDate() + 1); } - } - else { - return { - id: item.id, - title: item.title, - start: item.start, - end: endDate, - siteId: item.siteId + if (item.StatusHtml) { + return { + id: item.id, + title: item.title, + start: item.start, + end: endDate, + StatusHtml: item.StatusHtml, + siteId: item.siteId + } } - } - })) + else { + return { + id: item.id, + title: item.title, + start: item.start, + end: endDate, + siteId: item.siteId + } + } + })) + } } } - } function setCalendarGroup(group, data, calendarSuffix) { var hash = {}; diff --git a/Implem.Pleasanter/wwwroot/scripts/display.js b/Implem.Pleasanter/wwwroot/scripts/display.js index c204dc740..d1f93da74 100644 --- a/Implem.Pleasanter/wwwroot/scripts/display.js +++ b/Implem.Pleasanter/wwwroot/scripts/display.js @@ -220,6 +220,13 @@ ResetCalendarView_ko: '참조 사이트가 변경되었기 때문에 "필터", "그룹화 기준" 및 "열"을 재설정합니다.', ResetCalendarView_es: 'Restableciendo "Filtros", "Agrupar por" y "Columna" porque se cambió el sitio de referencia.', ResetCalendarView_vn: 'Đặt lại "Bộ lọc", "Nhóm theo" và "Cột" vì trang tham chiếu đã bị thay đổi.', + ResetKambanView: 'Resetting "Filters" and "Aggregation target" because the reference site has been changed.', + ResetKambanView_zh: '由于参考网站已更改,正在重置“过滤器”和“聚合目标”。', + ResetKambanView_ja: '基準となるサイトが変更されるため、「フィルタ」および「集計対象」をリセットします。', + ResetKambanView_de: 'Zurücksetzen von "Filtern" und "Aggregationsziel", da sich die Referenzseite geändert hat.', + ResetKambanView_ko: '기준 사이트가 변경되었기 때문에 "필터"와 "집계 대상"를 재설정합니다.', + ResetKambanView_es: 'Restableciendo "Filtros" y "Objetivo de agregación" porque el sitio de referencia ha cambiado.', + ResetKambanView_vn: 'Đặt lại "Bộ lọc" và "Mục tiêu tổng hợp" vì trang tham chiếu đã được thay đổi.', ResetOrder: 'Reset order', ResetOrder_zh: '重置顺序', ResetOrder_ja: 'リセット', diff --git a/Implem.Pleasanter/wwwroot/scripts/kamban.js b/Implem.Pleasanter/wwwroot/scripts/kamban.js index f2fe20fcf..62e87f857 100644 --- a/Implem.Pleasanter/wwwroot/scripts/kamban.js +++ b/Implem.Pleasanter/wwwroot/scripts/kamban.js @@ -1,37 +1,63 @@ -$p.setKamban = function () { +$p.setKamban = function (suffix) { + var suffixElArr = $('#MainForm').find('div[id^="KambanBody"].kambanbody').get(); + if (suffix) { + suffixElArr = $('#MainForm').find('div[id="KambanBody_' + suffix + '"].kambanbody').get(); + } + $('.kambanbody').addClass('no-drag'); $('#KambanValueField').toggle($('#KambanAggregateType').val() !== 'Count'); - $('#KambanBody .kamban-item').draggable({ - revert: 'invalid', - start: function () { - $(this).parent().droppable({ - disabled: true - }); - } - }); - $('#KambanBody .kamban-container').droppable({ - hoverClass: 'hover', - tolerance: 'intersect', - drop: function (e, ui) { - var data = $p.getData($('.main-form')); - var tableNamePrefix = $('#TableName').val() + '_'; - var dataX = $(this).attr('data-x'); - var dataY = $(this).attr('data-y'); - data["KambanId"] = $(ui.draggable).attr('data-id'); - if (dataX !== undefined) { - data[tableNamePrefix + $('#KambanGroupByX').val()] = dataX; + $(suffixElArr).each(function (index, value) { + var kambanSuffix = value.id.substring(value.id.indexOf('_')); + kambanSuffix = kambanSuffix.indexOf('_') === -1 ? '' : kambanSuffix; + $('#KambanBody' + kambanSuffix + ' .ui-widget-header').addClass('dashboard-kamban-header'); + $('#KambanBody' + kambanSuffix + ' .kamban-item').draggable({ + revert: 'invalid', + start: function () { + $(this).parent().droppable({ + disabled: true + }); + }, + helper: function () { + return $('
') + .addClass('dragging') + .append($('
') + .append($(this).text())).width($(this).width() + 10).height($(this).height() + 10); } - if (dataY !== undefined) { - data[tableNamePrefix + $('#KambanGroupByY').val()] = dataY; + }); + $('#KambanBody' + kambanSuffix + ' .kamban-container').droppable({ + hoverClass: 'hover', + tolerance: 'intersect', + drop: function (e, ui) { + $p.clearData(); + var control = ui.draggable; + var data = $p.getData($('.main-form')); + var tableNamePrefix = $('#KambanReferenceType' + kambanSuffix).val() + '_'; + var dataX = $(this).attr('data-x'); + var dataY = $(this).attr('data-y'); + data["KambanId"] = $(control).attr('data-id'); + if (dataX !== undefined) { + data[tableNamePrefix + $('#KambanGroupByX' + kambanSuffix).val()] = dataX; + } + if (dataY !== undefined) { + data[tableNamePrefix + $('#KambanGroupByY' + kambanSuffix).val()] = dataY; + } + if (kambanSuffix !== '') { + data.SiteId = control.attr('data-siteid'); + } + $p.set($('#KambanSuffix' + kambanSuffix), $('#KambanSuffix' + kambanSuffix).val()); + $p.send($('#KambanBody' + kambanSuffix)); } - $p.send($('#KambanBody')); - } + }) }); - $('#KambanBody .kamban-item').each(function () { - let offsetX, offsetY; + $(suffixElArr).each(function (index, value) { + $(this).find('.kamban-item').each(function () { + let offsetX, offsetY,kambanSuffix,siteId; $(this).on('touchstart', function (e) { + kambanSuffix = $(this).parents('[id^=Kamban]').attr('id').substring($(this).parents('[id^=Kamban]').attr('id').indexOf('_')); + kambanSuffix = kambanSuffix.indexOf('_') === -1 ? '' : kambanSuffix; const touch = e.touches[0]; offsetX = touch.clientX; offsetY = touch.clientY; + siteId = $(this).attr('data-siteid'); }); $(this).on('touchmove', function (e) { e.preventDefault(); @@ -40,7 +66,7 @@ const y = touch.clientY - offsetY; const rectDraggable = this.getBoundingClientRect(); $(this).css('z-index', 2); - $('#KambanBody .kamban-container').each(function () { + $('.kambanbody .kamban-container').each(function () { const rectDroppable = this.getBoundingClientRect(); if ( rectDraggable.left >= rectDroppable.left && @@ -59,7 +85,7 @@ const rectDraggable = this.getBoundingClientRect(); const id = $(this).attr('data-id'); let isDroppableIntoKambanContainer = false; - $('#KambanBody .kamban-container').each(function () { + $('#KambanBody' + kambanSuffix + ' .kamban-container').each(function () { const rectDroppable = this.getBoundingClientRect(); if ( rectDraggable.left >= rectDroppable.left && @@ -68,17 +94,22 @@ rectDraggable.top <= rectDroppable.bottom ) { var data = $p.getData($('.main-form')); - var tableNamePrefix = $('#TableName').val() + '_'; + var tableNamePrefix = $('#KambanReferenceType' + kambanSuffix).val() + '_'; var dataX = $(this).attr('data-x'); var dataY = $(this).attr('data-y'); data["KambanId"] = id; if (dataX !== undefined) { - data[tableNamePrefix + $('#KambanGroupByX').val()] = dataX; + data[tableNamePrefix + $('#KambanGroupByX' + kambanSuffix).val()] = dataX; } if (dataY !== undefined) { - data[tableNamePrefix + $('#KambanGroupByY').val()] = dataY; + data[tableNamePrefix + $('#KambanGroupByY' + kambanSuffix).val()] = dataY; + } + if (kambanSuffix !== '') { + data.SiteId = siteId; } - $p.send($('#KambanBody')); + $p.set($('#KambanSuffix' + kambanSuffix), $('#KambanSuffix' + kambanSuffix).val()); + $p.send($('#KambanBody' + kambanSuffix)); + $p.clearData('KambanSuffix' + kambanSuffix); isDroppableIntoKambanContainer = true; } }); @@ -87,4 +118,6 @@ } }); }); + + }) } \ No newline at end of file diff --git a/Implem.Pleasanter/wwwroot/scripts/responsive.js b/Implem.Pleasanter/wwwroot/scripts/responsive.js index c69fe9708..b403fb175 100644 --- a/Implem.Pleasanter/wwwroot/scripts/responsive.js +++ b/Implem.Pleasanter/wwwroot/scripts/responsive.js @@ -45,7 +45,7 @@ $(document).ready(function () { $('#Header').css({ 'box-shadow': 'rgba(0, 0, 0, 0.19) 0px 10px 20px, rgba(0, 0, 0, 0.23) 0px 6px 6px' }); - if (window.location.pathname.includes('index')) { + if (window.location.pathname.includes('index') && $('#TableName').val() !== 'Dashboards') { $('body thead').css({ 'top': `${heightHeader}px` }); diff --git a/Implem.Pleasanter/wwwroot/scripts/sitesettings.js b/Implem.Pleasanter/wwwroot/scripts/sitesettings.js index d645e8ff2..6a9ecfb75 100644 --- a/Implem.Pleasanter/wwwroot/scripts/sitesettings.js +++ b/Implem.Pleasanter/wwwroot/scripts/sitesettings.js @@ -254,7 +254,7 @@ $p.setRelatingColumn = function ($control) { } $p.openDashboardPartDialog = function ($control) { - $p.data.DashboardForm = {}; + $p.data.DashboardPartForm = {}; $p.openSiteSettingsDialog($control, '#DashboardPartDialog'); } @@ -269,10 +269,15 @@ $p.openDashboardPartTimeLineSitesDialog = function ($control) { } $p.openDashboardPartCalendarSitesDialog = function ($control) { - $p.data.TimeLineSitesForm = {}; + $p.data.CalendarSitesForm = {}; $p.openSiteSettingsDialog($control, '#DashboardPartCalendarSitesDialog'); } +$p.openDashboardPartKambanSitesDialog = function ($control) { + $p.data.KambanSitesForm = {}; + $p.openSiteSettingsDialog($control, '#DashboardPartKambanSitesDialog'); +} + $p.updateDashboardPartTimeLineSites = function ($control) { $p.send($control); } @@ -285,6 +290,7 @@ $p.confirmTimeLineSites = function (value) { $p.set($('#DashboardPartTimeLineSites'), args.timeLineSites); $p.set($('#DashboardPartBaseSiteId'), args.baseSiteId); $p.send($("#ClearDashboardView")); + $p.clearData('DashboardPartView', 'DashboardPartForm', 'startsWith'); $p.closeDialog($("#DashboardPartTimeLineSitesDialog")); } } @@ -296,7 +302,21 @@ $p.confirmCalendarSites = function (value) { $('#DashboardPartCalendarSitesValue').text(args.calendarSites); $p.set($('#DashboardPartCalendarSites'), args.calendarSites); $p.set($('#DashboardPartBaseSiteId'), args.baseSiteId); - $p.send($("#ClearDashboardView")); + $p.send($("#ClearDashboardCalendarView")); + $p.clearData('DashboardPartView', 'DashboardPartForm', 'startsWith'); $p.closeDialog($("#DashboardPartCalendarSitesDialog")); } +} + +$p.confirmKambanSites = function (value) { + var args = JSON.parse(value); + var result = confirm($p.display('ResetKambanView')); + if (result) { + $('#DashboardPartKambanSitesValue').text(args.kambanSites); + $p.set($('#DashboardPartKambanSites'), args.kambanSites); + $p.set($('#DashboardPartBaseSiteId'), args.baseSiteId); + $p.send($("#ClearDashboardKambanView")); + $p.clearData('DashboardPartView', 'DashboardPartForm', 'startsWith'); + $p.closeDialog($("#DashboardPartKambanSitesDialog")); + } } \ No newline at end of file diff --git a/Implem.Pleasanter/wwwroot/scripts/sitesettingsevents.js b/Implem.Pleasanter/wwwroot/scripts/sitesettingsevents.js index ae66ea4ee..45f161e7a 100644 --- a/Implem.Pleasanter/wwwroot/scripts/sitesettingsevents.js +++ b/Implem.Pleasanter/wwwroot/scripts/sitesettingsevents.js @@ -225,7 +225,15 @@ $('#DashboardPartCalendarTimePeriodField').toggle($("#DashboardPartCalendarType").val() === '1'); $('#DashboardPartCalendarFromToField').toggle(selected === '4'); $('#DashboardPartCalendarShowStatusField').toggle(selected === '4'); - $('#DashboardPartViewFiltersTabControl').toggle(selected === '1' || selected === '4'); + $('#DashboardPartKambanSitesField').toggle(selected === '5'); + $('#DashboardPartKambanGroupByXField').toggle(selected === '5'); + $('#DashboardPartKambanGroupByYField').toggle(selected === '5'); + $('#DashboardPartKambanAggregateTypeField').toggle(selected === '5'); + $('#DashboardPartKambanValueField').toggle(selected === '5'); + $('#DashboardPartKambanColumnsField').toggle(selected === '5'); + $('#DashboardPartKambanAggregationViewField').toggle(selected === '5'); + $('#DashboardPartKambanShowStatusField').toggle(selected === '5'); + $('#DashboardPartViewFiltersTabControl').toggle(selected === '1' || selected === '4' || selected === '5'); }); $(document).on('change','#DashboardPartCalendarType',function () { @@ -234,4 +242,9 @@ $('#DashboardPartCalendarTimePeriodField').toggle($("#DashboardPartCalendarType").val() === '1'); }); + $(document).on('change', '#DashboardPartKambanAggregateType', function () { + + $('#DashboardPartKambanValueField').toggle($('#DashboardPartKambanAggregateType').val() !== 'Count'); + + }); }); \ No newline at end of file diff --git a/Implem.Pleasanter/wwwroot/styles/site.css b/Implem.Pleasanter/wwwroot/styles/site.css index 5216e2420..9ab454077 100644 --- a/Implem.Pleasanter/wwwroot/styles/site.css +++ b/Implem.Pleasanter/wwwroot/styles/site.css @@ -653,7 +653,7 @@ pre { table-layout: fixed; } -.CalendarBody thead th { +div.Calendar > .CalendarBody > .grid > thead > tr > th { padding: 5px; text-align: center; border: solid 1px silver; @@ -986,23 +986,27 @@ th.calendar-header { fill: black; } -#KambanBody .kamban-row { +.kambanbody .kamban-row { border-bottom: dotted 1px silver; } -#KambanBody .kamban-container > div { +.kambanbody .kamban-container{ + background-color: white; +} + +.kambanbody .kamban-container > div { min-height: 30px; } -#KambanBody .kamban-container.hover { +.kambanbody .kamban-container.hover { background-color: whitesmoke; } -#KambanBody .kamban-container .kamban-item:last-child { +.kambanbody .kamban-container .kamban-item:last-child { margin: 3px 3px 30px 3px; } -#KambanBody .kamban-item { +.kambanbody .kamban-item { margin: 3px; padding: 4px 16px 4px 5px; background-color: lightgoldenrodyellow; @@ -1010,39 +1014,56 @@ th.calendar-header { position: relative; cursor: pointer; border-radius: 5px; + overflow: hidden; } - #KambanBody .kamban-item:hover { + .kambanbody .kamban-item:hover { background-color: white; border: solid 1px orange; } - #KambanBody .kamban-item.changed { + .kambanbody .kamban-item.changed { font-weight: bold; background-color: yellow; border: solid 1px orange; } - #KambanBody .kamban-item .ui-icon { + .kambanbody .kamban-item .ui-icon { position: absolute; top: 0px; right: 0px; } - #KambanBody .kamban-item > span { + .kambanbody .kamban-item > span { margin-right: 3px; } -#ImageLib .item { - width: 250px; - height: 250px; - float: left; - margin: 10px 10px 0px 0px; - padding: 10px; - border: solid 1px silver; - position: relative; - overflow: hidden; + .kambanbody .dragging { + padding: 5px; + background-color: lightgoldenrodyellow; + border-radius: 3px; + z-index: 50; + } + +.dashboard-kamban-header { + position: sticky; + top: -20px; + z-index: 1; } + .dashboard-kamban-header > th { + overflow-x: hidden; + } + + #ImageLib .item { + width: 250px; + height: 250px; + float: left; + margin: 10px 10px 0px 0px; + padding: 10px; + border: solid 1px silver; + position: relative; + overflow: hidden; + } #ImageLib .item .image { width: 100%; diff --git a/Implem.Plugins/Implem.Plugins.csproj b/Implem.Plugins/Implem.Plugins.csproj index c589380ad..cf309aa85 100644 --- a/Implem.Plugins/Implem.Plugins.csproj +++ b/Implem.Plugins/Implem.Plugins.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable disable diff --git a/Implem.TestAutomation/TestAutomation.cs b/Implem.TestAutomation/TestAutomation.cs index 65c72b1b2..979da0275 100644 --- a/Implem.TestAutomation/TestAutomation.cs +++ b/Implem.TestAutomation/TestAutomation.cs @@ -52,9 +52,9 @@ static void Main(string[] args) ResultFileName: autoTestScenario.ResultFileName, resultInitial: true); TestAutomationOperate.WriteLog( - logFileName : Parameters.ExtendedAutoTestSettings.LogFileName, - logMessage : $"Start case:{ autoTestScenario.CaseName}", - logInitial : true + logFileName: Parameters.ExtendedAutoTestSettings.LogFileName, + logMessage: $"Start case:{autoTestScenario.CaseName}", + logInitial: true ); autoTestScenario.TestCases .SelectMany(testCase => Parameters.ExtendedAutoTestOperations @@ -83,7 +83,10 @@ static void Main(string[] args) logFileName: Parameters.ExtendedAutoTestSettings.LogFileName, logMessage: ex.Message ); - Console.ReadKey(intercept: true); + if (!Console.IsInputRedirected && Console.KeyAvailable) + { + Console.ReadKey(intercept: true); + } } catch (Exception ex) { @@ -95,7 +98,10 @@ static void Main(string[] args) logFileName: Parameters.ExtendedAutoTestSettings.LogFileName, logMessage: ex.Message ); - Console.ReadKey(intercept: true); + if (!Console.IsInputRedirected && Console.KeyAvailable) + { + Console.ReadKey(intercept: true); + } } } diff --git a/Implem.TestAutomation/TestAutomationOperate.cs b/Implem.TestAutomation/TestAutomationOperate.cs index c6ac86c33..729acf5cc 100644 --- a/Implem.TestAutomation/TestAutomationOperate.cs +++ b/Implem.TestAutomation/TestAutomationOperate.cs @@ -818,7 +818,7 @@ public static void GetScreenShot(IWebDriver driver, string ActionName = null) VisibleItem(driver, "Footer"); VisibleItem(driver, "Message"); Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot(); - screenshot.SaveAsFile(file, ScreenshotImageFormat.Png); + screenshot.SaveAsFile(file); VisibleItem(driver, "MainCommandsContainer"); VisibleItem(driver, "Footer"); VisibleItem(driver, "Message"); diff --git a/Implem.TestAutomation/implem.TestAutomation.csproj b/Implem.TestAutomation/implem.TestAutomation.csproj index bf87abff6..52ae99b24 100644 --- a/Implem.TestAutomation/implem.TestAutomation.csproj +++ b/Implem.TestAutomation/implem.TestAutomation.csproj @@ -2,11 +2,11 @@ Exe - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 Linux @@ -25,13 +25,13 @@ - - - + + + - + diff --git a/Rds/Implem.IRds/Implem.IRds.csproj b/Rds/Implem.IRds/Implem.IRds.csproj index 8b9acd14b..f38b83ebd 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 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable diff --git a/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj b/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj index 58185ce13..b3a6bb9c3 100644 --- a/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj +++ b/Rds/Implem.PostgreSql/Implem.PostgreSql.csproj @@ -1,16 +1,16 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable - + diff --git a/Rds/Implem.SqlServer/Implem.SqlServer.csproj b/Rds/Implem.SqlServer/Implem.SqlServer.csproj index a44b98dcd..b15852af2 100644 --- a/Rds/Implem.SqlServer/Implem.SqlServer.csproj +++ b/Rds/Implem.SqlServer/Implem.SqlServer.csproj @@ -1,11 +1,11 @@  - net6.0 + net8.0 Copyright © Implem Inc 2014 - 2023 - 1.3.50.2 - 1.3.50.2 - 1.3.50.2 + 1.4.0.0 + 1.4.0.0 + 1.4.0.0 disable