feat(widgets): rebuild admin widgets page to match reference theme

- Replace transfer modal/admin-post flow with reference-style AJAX
  export/import/template dialogs (admin-transfer.js, TransferController)
- Customizer "移出模块" action, reference lazy form loading with t-notice
- Common fields use reference labels, dependencies, compact/inline rows,
  top/bottom-only extra spacing; form header with description/reminder
- Remove placement hint, template preview and legacy transfer code
- Fix widget audit (current_datetime stub, honor catalog common flags)
  and regenerate stale golden fixtures for posts_toc, quote, posts

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
kate522andClaude Fable 5 committed 2026-10-30 14:00:57 +08:00
1 parent ea80cd96cc
commit a579a5b00a
14 files changed
+698 -446

No files matched your search

@@ -6,7 +6,8 @@ const path = require('node:path')
const root = path.resolve(__dirname, '../..')
const core = require(path.join(root, 'assets/widgets/admin-core.js'))
const admin = fs.readFileSync(path.join(root, 'assets/widgets/admin.js'), 'utf8')
const controller = fs.readFileSync(path.join(root, 'src/WidgetSystem/AdminFormController.php'), 'utf8')
const wie = fs.readFileSync(path.join(root, 'assets/widgets/admin-transfer.js'), 'utf8')
const controller =fs.readFileSync(path.join(root, 'src/WidgetSystem/AdminFormController.php'), 'utf8')
const transfer = fs.readFileSync(path.join(root, 'src/WidgetSystem/TransferController.php'), 'utf8')
const renderer = fs.readFileSync(path.join(root, 'src/WidgetSystem/FormRenderer.php'), 'utf8')
const styles = fs.readFileSync(path.join(root, 'assets/widgets/admin.css'), 'utf8')
@@ -25,17 +26,22 @@ test('lazy form AJAX failures remain retryable and instance filters match WordPr
assert.match(controller, /apply_filters\('widget_form_callback', \$instance, \$widget\)/)
})
test('sidebar toolbars open one contextual import, export, or template dialog', () => {
assert.match(admin, /widgets-holder-wrap:not\(#available-widgets\)/)
assert.match(admin, /control-section-sidebar/)
assert.match(admin, /data-aksrt-transfer-action/)
assert.match(admin, /data-sidebar-id/)
assert.match(admin, /data-transfer-tab/)
assert.match(transfer, /aksrt-widget-transfer-modal__dialog/)
assert.match(transfer, /aksrt_widgets_template_preview/)
assert.doesNotMatch(transfer, /aksrt-widget-transfer__grid/)
assert.doesNotMatch(transfer, /function sidebar_select/)
assert.match(admin, /aksrt-widget-customizer-remove/)
test('sidebar toolbars drive reference-style AJAX export, import and template modals', () => {
assert.match(wie, /widgets-holder-wrap:not\(#available-widgets\)/)
assert.match(wie, /control-section-sidebar/)
assert.match(wie, /data-aksrt-wie-action/)
assert.match(wie, /data-sidebar-id/)
assert.match(wie, /aksrt-wie-btn-delete/)
assert.match(wie, /nonce: config\.transferNonce/)
for (const action of ['export_sidebar', 'import_sidebar', 'list_templates', 'import_template']) {
assert.match(wie, new RegExp(`aksrt_widgets_${action}`))
assert.match(transfer, new RegExp(`wp_ajax_aksrt_widgets_${action}`))
}
assert.match(transfer, /check_ajax_referer\(self::NONCE, 'nonce'\)/)
assert.match(transfer, /edit_theme_options/)
assert.doesNotMatch(transfer, /aksrt_widgets_template_preview|admin_post_|admin_notices/)
assert.doesNotMatch(admin, /data-aksrt-transfer-action|aksrt-widget-customizer-remove|aksrt-widget-form-lazy__load/)
assert.match(styles, /\.aksrt-wie-modal__dialog/)
})
test('widget fields follow the current CSF compact palette and cloneable group patterns', () => {
@@ -46,7 +52,9 @@ test('widget fields follow the current CSF compact palette and cloneable group p
assert.match(styles, /\.aksrt-widget-choices--palette/)
assert.match(styles, /\.aksrt-widget-repeater__bar/)
assert.match(styles, /\.customize-control-widget_form \.aksrt-widget-field__label/)
assert.match(admin, /if \(!response\?\.success \|\| !response\.data\) \{/)
assert.match(admin, /if \(!response\?\.success \|\| !response\.data\?\.html\) \{/)
assert.match(admin, /t-notice/)
assert.match(styles, /\.aksrt-widget-field\.is-compact/)
assert.match(admin, /responseJSON\?\.data\?\.message/)
assert.doesNotMatch(admin, /if \(!response\?\.success\) throw new Error/)
})