Skip to content

テナント・組織・グループ・ユーザーの管理画面に設定タブを足す ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.1.01.5.8.1

本体の標準機能ではありません

1.5.8.1 の管理画面(テナント・組織・グループ・ユーザー)には、一覧の列や既定値を変える設定がありません。このページは改修する場合の設計メモです。

目的は、次の設定を管理画面でも持てるようにすることです。

  • ガイド(一覧の上に出す GridGuide、編集画面の上に出す EditorGuide)
  • 一覧に出す列(GridColumns)
  • リンクのダイアログに出す列(LinkColumns)
  • エディタの設定(列ごとの既定値 DefaultInput、版を上げるタイミング AutoVerUpType)
  • 履歴一覧に出す列(HistoryColumns)
  • 列ごとのプロパティ(表示名・選択肢・既定値・入力必須など)
  • 外せない列(必ず表示する列)

前提にした現行実装(1.5.8.1) ​

タブの構成 ​

各管理画面の EditorTabs() が作るタブです。設定用のタブはありません。

画面タブ定義
テナント全般、SCIM トークン(SCIM が有効なとき)、サーバースクリプト(特権ユーザーで、契約とパラメータでサーバースクリプト・バックグラウンドサーバースクリプトが有効なとき)TenantUtilities.cs#L617-L641
グループ全般、メンバー・子グループ・変更履歴(いずれも既存のレコードだけ)GroupUtilities.cs#L1163
組織全般、変更履歴(既存のレコードで、公開表示でないとき)DeptUtilities.cs#L1098-L1113
ユーザー全般、メールアドレス(EnableManageTenant でないときの既存レコード)、変更履歴(既存のレコード)UserUtilities.cs#L1720-L1741

SiteSettings は毎回作り直している ​

管理画面の SiteSettings は SiteSettingsUtilities の TenantsSiteSettings()・DeptsSiteSettings()・GroupsSiteSettings()・UsersSiteSettings() が、DB を読まずにその場で作っています(SiteSettingsUtilities.cs#L521-L535 など)。

csharp
var ss = new SiteSettings()
{
    ReferenceType = "Tenants"
};
ss.Init(context: context);
ss.SetLinks(context: context);
ss.SetChoiceHash(context: context, withLink: false);
context.SetPermissionType(
    ss: ss,
    type: Permissions.Admins(context: context));
ss.TableType = tableTypes;
return ss;

そのため列の構成や既定値はいつも定義(Definition_Column)どおりです。

比較サイトテナント・組織・グループ・ユーザー
設定の保存先Sites.SiteSettings(JSON)なし
ガイドSites.GridGuide・Sites.EditorGuide の独立した列なし
GridColumns・EditorColumns・LinkColumns・HistoryColumns保存される定義の既定
列ごとの DefaultInput などColumnHash として保存される定義の既定
AutoVerUpType保存される未設定(null)

AutoVerUpType は、更新時に版を上げるか決める Versions.MustVerUp() が ss.AutoVerUpType を見ています(Versions.cs#L43-L61)。管理画面の各 Utilities も更新時に MustVerUp() を呼んでいるので、SiteSettings を保存できるようにすれば効きます。

AutoVerUpType値動作
Default1更新者が前回と違うか、前回の更新と日付が違うときに版を上げる(未設定もこの動作)
Always2毎回版を上げる
Disabled3版を上げない

設定の対象になる列 ​

一覧・エディタの設定の対象は、Definition_Column で GridEnabled・EditorEnabled が 1 の列です。1.5.8.1 の定義では次のとおりです(Required が 1 の列に ※)。

画面一覧・エディタの両方一覧だけエディタだけ
テナントLanguage・Theme・TimeZone--
グループGroupId※・GroupName※・Body・Disabled-LdapSync
組織DeptId※・DeptCode※・DeptName※・Body・Disabled--
ユーザーUserId※・LoginId※・Name・UserCode・Language※・Theme・Gender・Birthday・Body・Manager・Disabled・Lockout などDept・DeptCode・TimeZoneInfo※DeptId・TimeZone・Password・PasswordValidate※ など

既存の設定用の部品 ​

サイト設定の部品は SiteUtilities にあります。

部品公開範囲備考
GuideEditor(context, ss, siteModel)publicSiteModel を引数に取る(SiteUtilities.cs#L6386-L6390)
GridSettingsEditor(context, ss)private#L6574
EditorSettingsEditor(context, ss)private#L7402
LinksSettingsEditor(context, ss)private#L9588
HistoriesSettingsEditor(context, ss)private#L9665
GridColumnDialog(context, ss, column)・EditorColumnDialog(context, ss, column, titleColumns)public列のプロパティのダイアログ(#L6777、#L8121)

GuideEditor は SiteModel への依存を外すか、管理画面ごとに同じものを作る必要があります。一覧・エディタ・リンク・履歴の部品は SiteSettings だけを受け取るので、公開範囲を広げれば管理画面からも呼べます。

保存方式 ​

方式内容利点欠点
A. 各テーブルに SiteSettings 列を足すTenants・Groups・Depts・Users に SiteSettings nvarchar(max) を追加サイトと同じ形。SiteSettings クラスと既存の部品をそのまま使えるCodeDefiner の再実行と DB の列追加が要る
B. TenantSettings に入れるテナントの既存の TenantSettings に持たせるテナントなら列の追加が要らないテナント以外には入れ物がなく、形がそろわない
C. 画面ごとの設定クラスを作るGroupSettings などを新設型で管理できるクラスごとに列の追加が要る

A が素直です。ガイドはサイトでは独立した列ですが、SiteSettings クラスに GridGuide・EditorGuide のフィールドがあるので(SiteSettings.cs#L111-L113)、JSON の中に入れれば独立した列は要りません。テナントは既存の TenantSettings 列(バックグラウンドサーバースクリプトの保存先)とは別に SiteSettings 列を足すことになります。

図を読み込み中…

改修の手順 ​

1. 列の定義を足す ​

App_Data/Definitions/Definition_Column/ に Tenants_SiteSettings.json・Groups_SiteSettings.json・Depts_SiteSettings.json・Users_SiteSettings.json を足します。ひな形は Sites_SiteSettings.json です(Sites_SiteSettings.json)。

json
{
    "Id": "Tenants_SiteSettings",
    "ModelName": "Tenant",
    "TableName": "Tenants",
    "Label": "テナント",
    "ColumnName": "SiteSettings",
    "LabelText": "管理画面設定",
    "No": "XXX",
    "TypeName": "nvarchar",
    "TypeCs": "SiteSettings",
    "RecordingData": ".RecordingJson(context: context)",
    "MaxLength": "-1",
    "Nullable": "1",
    "NotForm": "1",
    "ByDataRow": "GetSiteSettings(context: context, dataRow: dataRow)",
    "BySession": "context.SessionData.Get(\"SiteSettings\")?.ToString().DeserializeSiteSettings(context: context) ?? new SiteSettings(context: context, referenceType: ReferenceType)"
}

No はテーブル内の既存の番号と重ならない値にします。

2. CodeDefiner を実行し、DB に列を足す ​

CodeDefiner を実行すると Libraries/DataSources/Rds.cs と TenantModel.cs・GroupModel.cs・DeptModel.cs・UserModel.cs が再生成され、SiteSettings プロパティと SQL の列が入ります。既存の環境には ALTER TABLE で 4 つのテーブルに列を足します。CodeDefiner の仕組みは CodeDefiner を参照してください。

3. SiteSettingsUtilities で DB から読む ​

csharp
public static SiteSettings TenantsSiteSettings(
    Context context,
    int tenantId = 0,
    Sqls.TableTypes tableTypes = Sqls.TableTypes.Normal)
{
    var ss = tenantId > 0
        ? Repository.ExecuteTable(
            context: context,
            statements: Rds.SelectTenants(
                column: Rds.TenantsColumn().SiteSettings(),
                where: Rds.TenantsWhere().TenantId(tenantId)))
                    .AsEnumerable()
                    .FirstOrDefault()
                    ?.String("SiteSettings")
                    ?.DeserializeSiteSettings(context: context)
                        ?? new SiteSettings() { ReferenceType = "Tenants" }
        : new SiteSettings() { ReferenceType = "Tenants" };
    ss.Init(context: context);
    ss.SetLinks(context: context);
    ss.SetChoiceHash(context: context, withLink: false);
    context.SetPermissionType(
        ss: ss,
        type: Permissions.Admins(context: context));
    ss.TableType = tableTypes;
    return ss;
}

4. タブと設定画面を足す ​

各 Utilities の EditorTabs() に、既存レコードのときだけ出るタブを足します(ガイド・一覧・リンク・エディタ・履歴)。

csharp
.Li(
    _using: tenantModel.MethodType != BaseModel.MethodTypes.New,
    action: () => hb
        .A(
            href: "#GridSettingsEditor",
            text: Displays.Grid(context: context)))
// LinksSettingsEditor・EditorSettingsEditor・HistoriesSettingsEditor・ガイドも同様

パネル側は SiteUtilities の部品を呼びます(公開範囲を広げたうえで)。

csharp
hb
    .GridSettingsEditor(context: context, ss: ss)
    .LinksSettingsEditor(context: context, ss: ss)
    .EditorSettingsEditor(context: context, ss: ss)
    .HistoriesSettingsEditor(context: context, ss: ss);

既存の「変更履歴」タブ(FieldSetHistories)は履歴を見るためのもので、ここで足す履歴の設定(履歴一覧に出す列)とは別のタブです。設定タブは管理者だけに出すよう、context.HasPrivilege などで制御します。

5. SetByForm と Update で保存する ​

SiteModel.SetByForm() は設定画面から来た値を SiteSettings に反映しています。同じ処理を各 XxxModel.SetByForm() に足し、Update() で SiteSettings 列に保存します。列のプロパティのダイアログから来た値は SiteSettings.SetColumnProperty() で反映します。

csharp
// SiteModel.SetByForm() の該当部分の形
case "AutoVerUpType":
    SiteSettings.AutoVerUpType = (Versions.AutoVerUpTypes)value.ToInt();
    break;

SiteSettings はサイト(期限付きテーブル・記録テーブルなど)向けの設計なので、カレンダー・ガント・カンバンなど管理画面に関係ない設定は画面に出さないようにします。

外せない列 ​

エディタの設定には「外せない列」の仕組みがすでにあります。EditorSettingsEditor が Required == true の列名を EditorColumnsNessesaryColumns、警告文を EditorColumnsNessesaryMessage という hidden に入れ(SiteUtilities.cs#L7700-L7710)、画面側の fieldselectable.js がその列を無効にしようとすると警告を出して止めます。

fieldselectable.js は '#' + columnsId + 'NessesaryColumns' と '#' + columnsId + 'NessesaryMessage' を探す汎用の作りです(fieldselectable.js#L118-L133)。一覧(GridColumns)にも同じ仕組みを付けるなら、サーバー側で GridColumnsNessesaryColumns と GridColumnsNessesaryMessage の hidden を出すだけで、スクリプトは変えずに済みます。

csharp
.Hidden(
    controlId: "GridColumnsNessesaryMessage",
    value: Messages.CanNotDisabled(
        context: context,
        data: "COLUMNNAME").Text)
.Hidden(
    controlId: "GridColumnsNessesaryColumns",
    value: Jsons.ToJson(
        ss.GetGridColumnNames()
            ?.Where(o => ss.GridColumn(o)?.Required == true)))

どの列を外せなくするかは Definition_Column の Required で決まります。前述の表のとおり、1.5.8.1 でもグループ・組織・ユーザーの ID や名前の列の多くはすでに Required が 1 です。

影響範囲 ​

  • CodeDefiner の生成物(Rds.cs・各 Model.cs)が変わるので、改修の差分は大きくなります。既存の管理画面の動作は、SiteSettings 列が空なら今と同じです。
  • 既存環境への展開では、4 つのテーブルへの列追加が要ります。

関連ページ ​

変更履歴

第1版レートリミッターの解説と、フォーム投稿の制限・ウイルススキャン・拡張子制限・外部検索エンジン・管理画面設定の改修・設計メモを追加