{
  "version": "1.0.0",
  "layout_name": "admin_board_settings",
  "permissions": [
    "sirsoft-board.settings.read"
  ],
  "extends": "_admin_base",
  "meta": {
    "title": "$t:sirsoft-board.admin.settings.title",
    "description": "$t:sirsoft-board.admin.settings.description"
  },
  "computed": {
    "isReadOnly": "{{!!settings?.data && settings?.data?.abilities?.can_update !== true}}",
    "isNotificationReadOnly": "{{boardNotificationDefinitions?.data?.abilities?.can_update !== true}}",
    "boardOptions": "{{(() => { const boards = boards_list?.data?.data ?? []; return boards.map(b => ({ value: b.id, label: b.name })); })()}}",
    "adminPermissions": "{{Object.entries(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(([key]) => key.startsWith('admin.'))}}",
    "userPermissions": "{{Object.entries(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(([key]) => !key.startsWith('admin.'))}}",
    "roleOptions": "{{(roles?.data?.data ?? []).map(r => ({ value: r.identifier, label: r.name ?? r.identifier }))}}",
    "adminPermKeys": "{{Object.entries(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(([key]) => key.startsWith('admin.')).map(([key]) => key)}}",
    "userPermKeys": "{{Object.entries(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(([key]) => !key.startsWith('admin.')).map(([key]) => key)}}",
    "allAdminChecked": "{{Object.keys(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(k => k.startsWith('admin.')).length > 0 && Object.keys(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(k => k.startsWith('admin.')).every(k => (_local.bulkApplyFields ?? []).includes(k))}}",
    "allUserChecked": "{{Object.keys(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(k => !k.startsWith('admin.')).length > 0 && Object.keys(settings?.data?.basic_defaults?.default_board_permissions ?? {}).filter(k => !k.startsWith('admin.')).every(k => (_local.bulkApplyFields ?? []).includes(k))}}"
  },
  "state": {
    "notificationDefinitionCurrentPage": 1,
    "notificationDefinitionTotalPages": 1,
    "notificationDefinitionTotalItems": 0
  },
  "transition_overlay": {
    "wait_for": [
      "settings",
      "boards_list",
      "roles",
      "board_types",
      "boardNotificationDefinitions",
      "notification_channels"
    ]
  },
  "initLocal": {
    "activeNotificationChannel": null,
    "editingDefinition": null,
    "editingTemplate": null,
    "editingRecipients": [],
    "editLang": "ko",
    "previewData": null,
    "notificationDefinitionFilter": {
      "search": "",
      "searchType": "all"
    },
    "expandedNotificationDefinitionIds": [],
    "expandedNotifications": {},
    "templateErrors": null,
    "isSaving": false,
    "recipientRoleSearchResults": [],
    "recipientUserSearchResults": []
  },
  "data_sources": [
    {
      "id": "settings",
      "label_key": "$t:sirsoft-board.editor.data_source.settings",
      "type": "api",
      "endpoint": "/api/modules/sirsoft-board/admin/settings",
      "method": "GET",
      "auto_fetch": true,
      "auth_required": true,
      "initLocal": "form",
      "refetchOnMount": true,
      "errorHandling": {
        "403": {
          "handler": "showErrorPage",
          "params": {
            "target": "content"
          }
        }
      }
    },
    {
      "id": "boards_list",
      "label_key": "$t:sirsoft-board.editor.data_source.boards_list",
      "type": "api",
      "endpoint": "/api/modules/sirsoft-board/admin/boards?per_page=999&fields=id,title",
      "method": "GET",
      "if": "{{(query.tab || _global.activeBoardSettingsTab || 'general') === 'basic_defaults'}}",
      "auto_fetch": true,
      "auth_required": true,
      "fallback": {
        "data": {
          "data": []
        }
      }
    },
    {
      "id": "roles",
      "label_key": "$t:sirsoft-board.editor.data_source.roles",
      "type": "api",
      "endpoint": "/api/admin/roles/active",
      "method": "GET",
      "if": "{{['basic_defaults', 'report_policy'].includes(query.tab || _global.activeBoardSettingsTab || 'general')}}",
      "auto_fetch": true,
      "auth_required": true,
      "fallback": {
        "data": []
      }
    },
    {
      "id": "board_types",
      "label_key": "$t:sirsoft-board.editor.data_source.board_types",
      "type": "api",
      "endpoint": "/api/modules/sirsoft-board/admin/board-types",
      "method": "GET",
      "if": "{{(query.tab || _global.activeBoardSettingsTab || 'general') === 'basic_defaults'}}",
      "auto_fetch": true,
      "auth_required": true,
      "fallback": {
        "data": []
      }
    },
    {
      "id": "boardNotificationDefinitions",
      "label_key": "$t:sirsoft-board.editor.data_source.boardNotificationDefinitions",
      "type": "api",
      "endpoint": "/api/admin/notification-definitions?extension_type=module&extension_identifier=sirsoft-board",
      "method": "GET",
      "if": "{{['notification_definitions', 'report_policy'].includes(query.tab || _global.activeBoardSettingsTab || 'general')}}",
      "auto_fetch": true,
      "auth_required": true,
      "params": {
        "page": "{{query.page || 1}}",
        "per_page": "{{query.per_page || 20}}",
        "search": "{{query.search}}",
        "search_type": "{{query.search_type}}"
      },
      "initLocal": {
        "_merge": "deep",
        "notificationDefinitionCurrentPage": "pagination.current_page",
        "notificationDefinitionTotalPages": "pagination.last_page",
        "notificationDefinitionTotalItems": "pagination.total"
      },
      "fallback": {
        "data": {
          "data": [],
          "pagination": []
        }
      }
    },
    {
      "id": "availableChannels",
      "label_key": "$t:sirsoft-board.editor.data_source.availableChannels",
      "type": "api",
      "endpoint": "/api/admin/notification-channels",
      "method": "GET",
      "if": "{{(query.tab || _global.activeBoardSettingsTab || 'general') === 'notification_definitions'}}",
      "auto_fetch": true,
      "auth_required": true,
      "fallback": {
        "data": {
          "channels": []
        }
      }
    },
    {
      "id": "boardIdentityPolicies",
      "label_key": "$t:sirsoft-board.editor.data_source.boardIdentityPolicies",
      "type": "api",
      "endpoint": "/api/admin/identity/policies",
      "method": "GET",
      "if": "{{(query.tab || _global.activeBoardSettingsTab || 'general') === 'identity_policies'}}",
      "auto_fetch": true,
      "auth_required": true,
      "params": {
        "source_identifier": "sirsoft-board",
        "scope": "{{query.scope ?? ''}}",
        "purpose": "{{query.purpose ?? ''}}",
        "search": "{{query.search ?? ''}}",
        "page": "{{query.page || 1}}",
        "per_page": "{{query.per_page || 10}}"
      },
      "fallback": {
        "data": {
          "data": [],
          "meta": {}
        }
      }
    },
    {
      "id": "boardIdentityPurposes",
      "label_key": "$t:sirsoft-board.editor.data_source.boardIdentityPurposes",
      "type": "api",
      "endpoint": "/api/identity/purposes",
      "method": "GET",
      "if": "{{(query.tab || _global.activeBoardSettingsTab || 'general') === 'identity_policies'}}",
      "auto_fetch": true,
      "auth_required": true,
      "fallback": {
        "data": []
      }
    },
    {
      "id": "identityProviders",
      "label_key": "$t:sirsoft-board.editor.data_source.identityProviders",
      "type": "api",
      "endpoint": "/api/admin/identity/providers",
      "method": "GET",
      "if": "{{(query.tab || _global.activeBoardSettingsTab || 'general') === 'identity_policies'}}",
      "auto_fetch": true,
      "auth_required": true,
      "fallback": {
        "data": []
      }
    }
  ],
  "init_actions": [
    {
      "handler": "setState",
      "params": {
        "target": "_local",
        "notificationDefinitionCurrentPage": "{{+(query.page || 1)}}"
      }
    }
  ],
  "slots": {
    "content": [
      {
        "id": "settings_content",
        "type": "basic",
        "name": "Div",
        "dataKey": "form",
        "trackChanges": true,
        "props": {
          "className": "admin-page-content-responsive"
        },
        "children": [
          {
            "id": "page_header_wrapper",
            "type": "basic",
            "name": "Div",
            "children": [
              {
                "id": "page_header",
                "type": "composite",
                "name": "PageHeader",
                "props": {
                  "title": "$t:sirsoft-board.admin.settings.title",
                  "description": "$t:sirsoft-board.admin.settings.description"
                }
              }
            ]
          },
          {
            "id": "sticky_header",
            "type": "basic",
            "name": "Div",
            "props": {
              "className": "sticky-section-header"
            },
            "children": [
              {
                "id": "header_content",
                "type": "basic",
                "name": "Div",
                "children": [
                  {
                    "id": "read_only_banner",
                    "type": "basic",
                    "name": "Div",
                    "if": "{{_computed.isReadOnly}}",
                    "props": {
                      "className": "alert-warning"
                    },
                    "children": [
                      {
                        "type": "basic",
                        "name": "Icon",
                        "props": {
                          "name": "lock",
                          "size": "lg",
                          "className": "text-amber-600 dark:text-amber-400 flex-shrink-0"
                        }
                      },
                      {
                        "type": "basic",
                        "name": "Span",
                        "props": {
                          "className": "text-warning-soft"
                        },
                        "text": "$t:sirsoft-board.admin.settings.read_only_message"
                      }
                    ]
                  },
                  {
                    "id": "tab_navigation",
                    "type": "composite",
                    "name": "TabNavigation",
                    "props": {
                      "tabs": [
                        {
                          "id": "general",
                          "label": "$t:sirsoft-board.admin.settings.tabs.general"
                        },
                        {
                          "id": "basic_defaults",
                          "label": "$t:sirsoft-board.admin.settings.tabs.basic_defaults"
                        },
                        {
                          "id": "report_policy",
                          "label": "$t:sirsoft-board.admin.settings.tabs.report_policy"
                        },
                        {
                          "id": "spam_security",
                          "label": "$t:sirsoft-board.admin.settings.tabs.spam_security"
                        },
                        {
                          "id": "seo",
                          "label": "$t:sirsoft-board.admin.settings.tabs.seo"
                        },
                        {
                          "id": "notification_definitions",
                          "label": "$t:sirsoft-board.admin.settings.tabs.notification_definitions"
                        },
                        {
                          "id": "identity_policies",
                          "label": "$t:sirsoft-board.admin.settings.tabs.identity_policies"
                        }
                      ],
                      "activeTabId": "{{_global.activeBoardSettingsTab || query.tab || 'general'}}",
                      "variant": "default"
                    },
                    "actions": [
                      {
                        "event": "onTabChange",
                        "type": "change",
                        "handler": "sequence",
                        "params": {
                          "actions": [
                            {
                              "handler": "setState",
                              "params": {
                                "target": "local",
                                "errors": null
                              }
                            },
                            {
                              "handler": "setState",
                              "params": {
                                "target": "global",
                                "activeBoardSettingsTab": "{{$args[0]}}"
                              }
                            },
                            {
                              "handler": "navigate",
                              "params": {
                                "path": "/admin/boards/settings",
                                "query": {
                                  "tab": "{{$args[0]}}"
                                },
                                "replace": true
                              }
                            },
                            {
                              "handler": "scrollIntoView",
                              "params": {
                                "selector": "#tab_content",
                                "behavior": "instant",
                                "block": "start",
                                "waitForElement": true,
                                "timeout": 1000
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                ]
              },
              {
                "id": "sub_tab_navigation",
                "type": "composite",
                "name": "TabNavigationScroll",
                "if": "{{(_global.activeBoardSettingsTab || query.tab || 'general') === 'basic_defaults'}}",
                "props": {
                  "tabs": [
                    {
                      "id": "basic",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.basic"
                    },
                    {
                      "id": "permissions",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.permissions"
                    },
                    {
                      "id": "list",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.list"
                    },
                    {
                      "id": "post",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.post"
                    },
                    {
                      "id": "reply",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.reply"
                    },
                    {
                      "id": "comment",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.comment"
                    },
                    {
                      "id": "attachment",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.attachment"
                    },
                    {
                      "id": "notification",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.notification"
                    },
                    {
                      "id": "bulk_apply",
                      "label": "$t:sirsoft-board.admin.settings.board_settings_tabs.bulk_apply"
                    }
                  ],
                  "className": "sub-tab-nav",
                  "sectionIdPrefix": "",
                  "enableScrollSpy": true,
                  "scrollContainerId": "right_content_area",
                  "scrollSpyOffset": 180,
                  "scrollOffset": 180
                }
              }
            ]
          },
          {
            "id": "tab_content",
            "type": "basic",
            "name": "Div",
            "props": {
              "className": "tab-content"
            },
            "children": [
              {
                "id": "validation_error",
                "type": "basic",
                "name": "Div",
                "if": "{{_local.errors}}",
                "props": {
                  "className": "alert-danger"
                },
                "children": [
                  {
                    "type": "basic",
                    "name": "Div",
                    "props": {
                      "className": "flex gap-3"
                    },
                    "children": [
                      {
                        "type": "basic",
                        "name": "Icon",
                        "props": {
                          "name": "triangle-exclamation",
                          "size": "lg",
                          "className": "text-red-600 dark:text-red-400 flex-shrink-0 mt-0.5"
                        }
                      },
                      {
                        "type": "basic",
                        "name": "Div",
                        "children": [
                          {
                            "type": "basic",
                            "name": "H3",
                            "props": {
                              "className": "text-error-strong"
                            },
                            "text": "$t:sirsoft-board.admin.settings.validation_error"
                          },
                          {
                            "type": "basic",
                            "name": "P",
                            "if": "{{typeof _local.errors === 'string'}}",
                            "props": {
                              "className": "text-error-soft mt-2"
                            },
                            "text": "{{_local.errors}}"
                          },
                          {
                            "type": "basic",
                            "name": "Ul",
                            "if": "{{typeof _local.errors === 'object' && Object.keys(_local.errors).length > 0}}",
                            "props": {
                              "className": "mt-2 list-disc list-inside space-y-1"
                            },
                            "iteration": {
                              "source": "Object.entries(_local.errors ?? {}).flatMap(([field, messages]) => Array.isArray(messages) ? messages : [messages])",
                              "item_var": "message"
                            },
                            "children": [
                              {
                                "type": "basic",
                                "name": "Li",
                                "props": {
                                  "className": "text-error-soft"
                                },
                                "text": "{{message}}"
                              }
                            ]
                          }
                        ]
                      }
                    ]
                  }
                ]
              },
              {
                "partial": "partials/admin_board_settings/_tab_general.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_basic.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_permissions.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_list.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_post.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_reply.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_comment.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_attachment.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_notification.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_board_settings_bulk_apply.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_report_policy.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_spam_security.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_seo.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_notification_definitions.json"
              },
              {
                "partial": "partials/admin_board_settings/_tab_identity_policies.json"
              },
              {
                "id": "footer_buttons",
                "type": "basic",
                "name": "Div",
                "if": "{{!_computed.isReadOnly}}",
                "props": {
                  "className": "sticky-footer-buttons"
                },
                "children": [
                  {
                    "type": "basic",
                    "name": "Div",
                    "if": "{{_local.hasChanges}}",
                    "props": {
                      "className": "flex-center gap-1.5 text-sm text-amber-600 dark:text-amber-400 mr-auto"
                    },
                    "children": [
                      {
                        "type": "basic",
                        "name": "Icon",
                        "props": {
                          "name": "circle-dot",
                          "size": "xs"
                        }
                      },
                      {
                        "type": "basic",
                        "name": "Span",
                        "text": "$t:sirsoft-board.admin.settings.unsaved_changes"
                      }
                    ]
                  },
                  {
                    "id": "footer_cancel_button",
                    "type": "basic",
                    "name": "Button",
                    "props": {
                      "type": "button",
                      "className": "btn btn-secondary text-sm"
                    },
                    "actions": [
                      {
                        "type": "click",
                        "handler": "navigate",
                        "params": {
                          "path": "/admin"
                        }
                      }
                    ],
                    "children": [
                      {
                        "type": "basic",
                        "name": "Span",
                        "text": "$t:common.cancel"
                      }
                    ]
                  },
                  {
                    "id": "footer_save_button",
                    "type": "basic",
                    "name": "Button",
                    "props": {
                      "type": "button",
                      "disabled": "{{_computed.isReadOnly || !_local.hasChanges || _local.isSaving}}",
                      "className": "btn btn-primary flex-center gap-1.5 text-sm"
                    },
                    "actions": [
                      {
                        "type": "click",
                        "handler": "sequence",
                        "params": {
                          "actions": [
                            {
                              "handler": "setState",
                              "params": {
                                "target": "local",
                                "isSaving": true,
                                "errors": null
                              }
                            },
                            {
                              "handler": "apiCall",
                              "auth_required": true,
                              "target": "/api/modules/sirsoft-board/admin/settings",
                              "params": {
                                "method": "PUT",
                                "body": "{{(function() { const tab = _global.activeBoardSettingsTab || query.tab || 'general'; const form = _local.form || {}; if (tab === 'general') { return { _tab: 'general', display: form.display || {} }; } if (tab === 'report_policy') { return { _tab: 'report_policy', report_policy: form.report_policy || {}, spam_security: form.spam_security || {}, report_permissions: form.report_permissions || {} }; } if (tab === 'spam_security') { return { _tab: 'spam_security', spam_security: form.spam_security || {} }; } if (tab === 'seo') { return { _tab: 'seo', seo: form.seo || {} }; } if (tab === 'notification_definitions') { return { _tab: 'notifications', notifications: { channels: form.notifications?.channels || [] } }; } return { _tab: 'basic_defaults', basic_defaults: form.basic_defaults || {}, notifications: form.notifications || {} }; })()}}"
                              },
                              "onSuccess": [
                                {
                                  "handler": "setState",
                                  "params": {
                                    "target": "local",
                                    "isSaving": false,
                                    "hasChanges": false
                                  }
                                },
                                {
                                  "handler": "refetchDataSource",
                                  "params": {
                                    "dataSourceId": "settings"
                                  }
                                },
                                {
                                  "handler": "refetchDataSource",
                                  "params": {
                                    "dataSourceId": "boards_list"
                                  }
                                },
                                {
                                  "handler": "refetchDataSource",
                                  "params": {
                                    "dataSourceId": "roles"
                                  }
                                },
                                {
                                  "handler": "refetchDataSource",
                                  "params": {
                                    "dataSourceId": "board_types"
                                  }
                                },
                                {
                                  "handler": "toast",
                                  "params": {
                                    "type": "success",
                                    "message": "$t:sirsoft-board.admin.settings.save_success"
                                  }
                                }
                              ],
                              "onError": [
                                {
                                  "handler": "setState",
                                  "params": {
                                    "target": "local",
                                    "isSaving": false,
                                    "errors": "{{error.errors}}"
                                  }
                                },
                                {
                                  "handler": "toast",
                                  "params": {
                                    "type": "error",
                                    "message": "$t:sirsoft-board.admin.settings.save_error"
                                  }
                                }
                              ]
                            }
                          ]
                        }
                      }
                    ],
                    "children": [
                      {
                        "type": "basic",
                        "name": "Icon",
                        "if": "{{_local.isSaving}}",
                        "props": {
                          "name": "spinner",
                          "size": "sm",
                          "spin": true
                        }
                      },
                      {
                        "type": "basic",
                        "name": "Span",
                        "if": "{{!_local.isSaving}}",
                        "text": "$t:common.save"
                      },
                      {
                        "type": "basic",
                        "name": "Span",
                        "if": "{{_local.isSaving}}",
                        "text": "$t:common.saving"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "modals": [
    {
      "partial": "partials/admin_board_settings/_bulk_apply_modal.json"
    },
    {
      "partial": "partials/admin_board_form/_board_type_manage_modal.json"
    },
    {
      "partial": "partials/admin_board_settings/_modal_notification_template_edit.json"
    },
    {
      "partial": "partials/admin_board_settings/_modal_notification_template_preview.json"
    },
    {
      "partial": "partials/admin_board_settings/_modal_notification_definition_reset.json"
    },
    {
      "partial": "partials/admin_board_settings/_modal_identity_policy_form.json"
    },
    {
      "partial": "partials/admin_board_settings/_modal_identity_policy_delete.json"
    }
  ]
}
