Files
X-Financial/web/src/views/scripts/AuditView.js

823 lines
26 KiB
JavaScript
Raw Normal View History

import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import AuditAssetList from '../../components/audit/AuditAssetList.vue'
import AuditJsonRiskRuleDetail from '../../components/audit/AuditJsonRiskRuleDetail.vue'
import AuditRuleDialogs from '../../components/audit/AuditRuleDialogs.vue'
import AuditSpreadsheetChangeDrawer from '../../components/audit/AuditSpreadsheetChangeDrawer.vue'
import AuditSpreadsheetRuleDetail from '../../components/audit/AuditSpreadsheetRuleDetail.vue'
import AuditVersionTimelineDrawer from '../../components/audit/AuditVersionTimelineDrawer.vue'
import TableLoadingState from '../../components/shared/TableLoadingState.vue'
import { useSystemState } from '../../composables/useSystemState.js'
import { useToast } from '../../composables/useToast.js'
import { isFinanceUser, isManagerUser, isPlatformAdminUser } from '../../utils/accessControl.js'
import { useAuditAssetData } from './useAuditAssetData.js'
import { buildAuditDetailTopBar } from './auditViewDetailTopBar.js'
import { useAuditListFilters } from './auditViewListFilters.js'
import { useAuditRuleReviewFlow } from './useAuditRuleReviewFlow.js'
import { useAuditRuleVersionActions } from './useAuditRuleVersionActions.js'
import { useAuditRiskRuleActions } from './useAuditRiskRuleActions.js'
import { useAuditRiskRuleCreateFlow } from './useAuditRiskRuleCreateFlow.js'
import { useAuditRiskRuleJsonEditor } from './useAuditRiskRuleJsonEditor.js'
import { useAuditSpreadsheetEditor } from './useAuditSpreadsheetEditor.js'
import { useAuditVersionTimeline } from './useAuditVersionTimeline.js'
import {
TAB_META,
STATUS_OPTIONS,
ENABLED_STATE_OPTIONS,
ONLINE_STATE_OPTIONS,
RISK_SCENARIO_OPTIONS,
normalizeText,
readConfigJson,
buildPreviewRuleDetail,
} from './auditViewModel.js'
import {
RISK_RULE_BUSINESS_STAGE_OPTIONS,
RISK_RULE_EXPENSE_CATEGORY_OPTIONS,
} from './auditViewRiskRuleModel.js'
export default {
name: 'AuditView',
components: {
AuditAssetList,
AuditJsonRiskRuleDetail,
AuditRuleDialogs,
AuditSpreadsheetChangeDrawer,
AuditSpreadsheetRuleDetail,
AuditVersionTimelineDrawer,
TableLoadingState
},
emits: ['detail-open-change', 'detail-topbar-change'],
setup(_, { emit }) {
const { toast } = useToast()
const { currentUser } = useSystemState()
const tabs = Object.entries(TAB_META).map(([id, meta]) => ({
id,
label: meta.label
}))
const activeType = ref('financialRules')
const selectedSkill = ref(null)
const keyword = ref('')
const activeFilterPopover = ref('')
const selectedDomain = ref('')
const selectedOwner = ref('')
const selectedRiskLevel = ref('')
const selectedStatus = ref('')
const selectedRiskScenario = ref('')
const selectedOnlineState = ref('')
const selectedEnabledState = ref('')
const actionState = ref('')
const riskRuleAttachmentOptions = [
{ label: '是', value: true },
{ label: '否', value: false }
]
const isAdmin = computed(() => isPlatformAdminUser(currentUser.value))
const isRuleManager = computed(() => isManagerUser(currentUser.value))
const isFinance = computed(() => isFinanceUser(currentUser.value))
const activeMeta = computed(() => TAB_META[activeType.value])
const activeTabLabel = computed(() => activeMeta.value.label)
const searchPlaceholder = computed(() => activeMeta.value.searchPlaceholder)
const createButtonLabel = computed(() => activeMeta.value.createButtonLabel)
const hintText = computed(() => activeMeta.value.hintText)
const tableColumns = computed(() => activeMeta.value.tableColumns)
const showRuntimeColumn = computed(() => activeMeta.value.showRuntimeColumn !== false)
const showMetricColumn = computed(() => activeMeta.value.showMetricColumn !== false)
const showVersionColumn = computed(() => activeMeta.value.showVersionColumn !== false)
const showStatusColumn = computed(() => activeMeta.value.showStatusColumn !== false)
const showOnlineColumn = computed(() => false)
const showEnabledColumn = computed(() => activeMeta.value.showEnabledColumn === true)
const selectedSkillIsRule = computed(() => selectedSkill.value?.type === 'rules')
const selectedSkillUsesSpreadsheet = computed(
() => selectedSkillIsRule.value && Boolean(selectedSkill.value?.usesSpreadsheetRule)
)
const selectedSkillUsesJsonRisk = computed(
() => selectedSkillIsRule.value && Boolean(selectedSkill.value?.usesJsonRiskRule)
)
const canManageSelected = computed(
() => isRuleManager.value && Boolean(selectedSkill.value) && !selectedSkill.value?.isPreviewMock
)
const canAdminOperateSelected = computed(
() => isAdmin.value && Boolean(selectedSkill.value) && !selectedSkill.value?.isPreviewMock
)
const canEditSelected = computed(
() =>
Boolean(selectedSkill.value) &&
!selectedSkill.value?.isPreviewMock &&
(isAdmin.value || isFinance.value)
)
const latestRiskRuleTestSummary = computed(() => selectedSkill.value?.latestTestSummary || null)
const riskRuleTestPassed = computed(() => Boolean(latestRiskRuleTestSummary.value?.test_passed))
const riskRuleInReview = computed(
() => selectedSkillUsesJsonRisk.value && selectedSkill.value?.statusValue === 'review'
)
const riskRuleGenerationBusy = computed(
() => selectedSkillUsesJsonRisk.value && selectedSkill.value?.statusValue === 'generating'
)
const riskRuleGenerationFailed = computed(
() => selectedSkillUsesJsonRisk.value && selectedSkill.value?.statusValue === 'failed'
)
const canOpenRiskRuleTest = computed(
() =>
selectedSkillUsesJsonRisk.value &&
canAdminOperateSelected.value &&
Boolean(selectedSkill.value?.id) &&
!riskRuleGenerationBusy.value &&
!riskRuleGenerationFailed.value
)
const canDeleteRiskRule = computed(
() =>
selectedSkillUsesJsonRisk.value &&
canAdminOperateSelected.value &&
Boolean(selectedSkill.value?.id) &&
!normalizeText(selectedSkill.value?.publishedVersion).replace('-', '')
)
const canOpenRiskRuleReviewSubmit = computed(() => false)
const canSubmitRiskRuleReview = computed(
() =>
canOpenRiskRuleReviewSubmit.value &&
riskRuleTestPassed.value
)
const canReturnRiskRule = computed(() => false)
const riskRuleHasPublishableRevision = computed(() => {
const revision = selectedSkill.value?.configJson?.revision_draft
return selectedSkillUsesJsonRisk.value && revision &&
revision.generation_status === 'completed' &&
normalizeText(selectedSkill.value?.workingVersion).replace('-', '') &&
selectedSkill.value?.workingVersion !== selectedSkill.value?.publishedVersion
})
const canPublishRiskRule = computed(
() =>
Boolean(riskRuleHasPublishableRevision.value) &&
canManageSelected.value &&
riskRuleTestPassed.value &&
!detailBusy.value
)
const canToggleRiskRuleEnabled = computed(
() => selectedSkillUsesJsonRisk.value && canManageSelected.value
)
const canEditRiskRuleDraft = computed(
() =>
selectedSkillUsesJsonRisk.value &&
(canEditSelected.value || canManageSelected.value) &&
!detailBusy.value &&
!riskRuleGenerationBusy.value &&
!normalizeText(selectedSkill.value?.publishedVersion).replace('-', '')
)
const canCreateRiskRuleRevision = computed(
() =>
selectedSkillUsesJsonRisk.value &&
(canEditSelected.value || canManageSelected.value) &&
!detailBusy.value &&
!riskRuleGenerationBusy.value &&
!riskRuleGenerationFailed.value &&
Boolean(normalizeText(selectedSkill.value?.publishedVersion).replace('-', ''))
)
const canEditMarkdown = computed(() => selectedSkillIsRule.value && canEditSelected.value)
const isDisplayingWorkingVersion = computed(
() => selectedSkill.value?.displayVersion === selectedSkill.value?.workingVersion
)
const canUploadSpreadsheet = computed(
() =>
canEditSelected.value &&
selectedSkillUsesSpreadsheet.value &&
!detailBusy.value
)
const canDownloadSpreadsheet = computed(
() =>
selectedSkillUsesSpreadsheet.value &&
Boolean(selectedSkill.value?.id) &&
!detailBusy.value
)
const canEditSpreadsheetInline = computed(
() =>
selectedSkillUsesSpreadsheet.value &&
(selectedSkill.value?.isPreviewMock || canEditSelected.value)
)
const selectedSpreadsheetFileName = computed(
() =>
normalizeText(selectedSkill.value?.ruleDocument?.file_name) || '未上传规则表'
)
const {
versionSwitchTarget,
versionTimelineOpen,
versionTimelineLoading,
versionTimelineError,
selectedVersionTimelineItems,
loadVersionTimeline: loadVersionTimelineInState,
openVersionTimeline: openVersionTimelineInState,
closeVersionTimeline: closeVersionTimelineInState,
clearVersionTimelineState,
openVersionSwitch: openVersionSwitchInState,
cancelVersionSwitch: cancelVersionSwitchInState,
confirmVersionSwitch: confirmVersionSwitchInState
} = useAuditVersionTimeline({
selectedSkill,
toast
})
const {
loadRiskRuleJson,
saveRiskRuleJson,
formatRiskRuleJson,
downloadRiskRuleJson
} = useAuditRiskRuleJsonEditor({
selectedSkill,
canEditMarkdown,
actionState,
toast
})
const detailBusy = computed(() => Boolean(actionState.value))
const {
loading,
errorMessage,
detailLoading,
detailError,
assetBuckets,
currentAssets,
loadRuns,
loadAssets,
refreshCurrentAssets,
loadSelectedAssetDetail,
mergeSelectedRuleLifecycle
} = useAuditAssetData({
activeType,
activeMeta,
selectedSkill,
loadVersionTimeline: loadVersionTimelineInState,
loadSpreadsheetChangeRecords: (...args) => loadSpreadsheetChangeRecords(...args),
loadRiskRuleJson,
toast
})
const {
spreadsheetUploadInput,
spreadsheetOnlyOfficeLoading,
spreadsheetOnlyOfficeError,
spreadsheetOnlyOfficeReady,
spreadsheetOnlyOfficeHostId,
spreadsheetChangeDetailOpen,
selectedSpreadsheetChangeRecord,
selectedSpreadsheetChangeRecords,
selectedSpreadsheetChangeSheetRows,
selectedSpreadsheetChangeCellRows,
destroySpreadsheetOnlyOfficeEditor,
mountSpreadsheetOnlyOfficeEditor,
triggerSpreadsheetUpload,
downloadSpreadsheetFile,
handleSpreadsheetFileInput,
loadSpreadsheetChangeRecords,
openSpreadsheetChangeDetail,
closeSpreadsheetChangeDetail
} = useAuditSpreadsheetEditor({
selectedSkill,
selectedSkillUsesSpreadsheet,
canEditSpreadsheetInline,
canUploadSpreadsheet,
canDownloadSpreadsheet,
selectedSpreadsheetFileName,
actionState,
refreshCurrentAssets,
loadSelectedAssetDetail,
resolveActor,
toast
})
const {
canCreateRiskRule,
riskRuleCreateOpen,
riskRuleCreateForm,
riskRuleCreateBusy,
openRiskRuleCreateDialog,
closeRiskRuleCreateDialog,
submitRiskRuleCreate,
stopAllRiskRuleGenerationPolls
} = useAuditRiskRuleCreateFlow({
activeType,
isRuleManager,
detailBusy,
actionState,
assetBuckets,
refreshCurrentAssets,
resolveActor,
toast
})
const {
saveRuleMarkdown,
saveRuleRuntimeJson,
activateSelectedRule,
restoreSelectedVersion
} = useAuditRuleVersionActions({
selectedSkill,
selectedSkillIsRule,
canEditMarkdown,
canManageSelected,
actionState,
detailBusy,
refreshCurrentAssets,
loadSelectedAssetDetail,
resolveActor,
toast
})
const {
reviewSubmitOpen,
reviewSubmitVersion,
reviewSubmitReviewer,
reviewSubmitReviewerLoading,
reviewSubmitReviewerOptions,
canSubmitReview,
hasReviewSubmitReviewers,
canReviewSelected,
reviewSelectedRule,
openSubmitReviewDialog,
closeSubmitReviewDialog,
submitSelectedRuleForReview
} = useAuditRuleReviewFlow({
selectedSkill,
selectedSkillIsRule,
selectedSkillUsesJsonRisk,
canEditSelected,
canManageSelected,
isDisplayingWorkingVersion,
canOpenRiskRuleReviewSubmit,
riskRuleTestPassed,
detailBusy,
actionState,
refreshCurrentAssets,
loadSelectedAssetDetail,
resolveActor,
toast
})
const {
riskRuleTestOpen,
riskRuleDeleteOpen,
riskRuleReturnOpen,
riskRulePublishOpen,
riskRuleReturnNote,
riskRuleEditOpen,
riskRuleEditMode,
riskRuleEditForm,
resetRiskRuleActionDialogs,
openRiskRuleTestDialog,
closeRiskRuleTestDialog,
handleRiskRuleReportSaved,
openRiskRuleEditDialog,
closeRiskRuleEditDialog,
submitRiskRuleEdit,
openDeleteRiskRuleDialog,
closeDeleteRiskRuleDialog,
deleteSelectedRiskRule,
openReturnRiskRuleDialog,
closeReturnRiskRuleDialog,
returnSelectedRiskRule,
openPublishRiskRuleDialog,
closePublishRiskRuleDialog,
publishSelectedRiskRule,
toggleSelectedRiskRuleEnabled
} = useAuditRiskRuleActions({
selectedSkill,
detailBusy,
actionState,
canOpenRiskRuleTest,
canDeleteRiskRule,
canReturnRiskRule,
canPublishRiskRule,
riskRuleHasPublishableRevision,
canToggleRiskRuleEnabled,
canEditRiskRuleDraft,
canCreateRiskRuleRevision,
riskRuleTestPassed,
refreshCurrentAssets,
loadSelectedAssetDetail,
mergeSelectedRuleLifecycle,
closeDetail,
resolveActor,
toast
})
const showReviewNote = computed(
() => selectedSkillIsRule.value && (selectedSkill.value?.reviewNote || selectedSkill.value?.reviewTimeLabel)
)
const {
activeFilterTokens,
auditEmptyState,
domainOptions,
ownerOptions,
riskLevelOptions,
selectedDomainLabel,
selectedEnabledStateLabel,
selectedOnlineStateLabel,
selectedOwnerLabel,
selectedRiskLevelLabel,
selectedRiskScenarioLabel,
selectedStatusLabel,
showEnabledFilter,
showOnlineFilter,
showOwnerFilter,
showRiskLevelFilter,
showRiskScenarioFilter,
showStatusFilter,
visibleSkills
} = useAuditListFilters({
activeType,
activeTabLabel,
currentAssets,
keyword,
selectedDomain,
selectedEnabledState,
selectedOnlineState,
selectedOwner,
selectedRiskLevel,
selectedRiskScenario,
selectedStatus
})
const canActivateSelected = computed(() => {
if (!selectedSkillIsRule.value || !canManageSelected.value || detailBusy.value) {
return false
}
return (
isDisplayingWorkingVersion.value &&
selectedSkill.value?.reviewStatusValue === 'approved' &&
selectedSkill.value?.workingVersion !== selectedSkill.value?.publishedVersion
)
})
const activateBlockedReason = computed(() => {
if (!selectedSkillIsRule.value) {
return ''
}
if (selectedSkill.value?.isPreviewMock) {
return '当前为页面预览态,暂不执行真实审核和上线。'
}
if (!canManageSelected.value) {
return '仅高级财务人员可执行审核和上线。'
}
if (!isDisplayingWorkingVersion.value) {
return '请先切回当前工作版本,再执行审核或上线。'
}
if (selectedSkill.value?.workingVersion === selectedSkill.value?.publishedVersion) {
return '当前工作版本已经是线上版本。'
}
if (selectedSkill.value?.reviewStatusValue !== 'approved') {
return '当前规则版本未审核通过,不能上线。'
}
return ''
})
const auditDetailTopBar = computed(() =>
buildAuditDetailTopBar({
skill: selectedSkill.value,
usesJsonRiskRule: selectedSkillUsesJsonRisk.value
})
)
watch(
selectedSkill,
(value) => {
emit('detail-open-change', Boolean(value))
},
{ immediate: true }
)
watch(
auditDetailTopBar,
(value) => {
emit('detail-topbar-change', value)
},
{ immediate: true, deep: true }
)
watch(
() => [
selectedSkill.value?.id || '',
selectedSkill.value?.loading ? '1' : '0',
selectedSkill.value?.usesSpreadsheetRule ? '1' : '0'
],
async () => {
if (!selectedSkillUsesSpreadsheet.value || selectedSkill.value?.loading) {
destroySpreadsheetOnlyOfficeEditor()
spreadsheetOnlyOfficeError.value = ''
spreadsheetOnlyOfficeLoading.value = false
return
}
await mountSpreadsheetOnlyOfficeEditor()
}
)
watch(activeType, () => {
destroySpreadsheetOnlyOfficeEditor()
selectedSkill.value = null
clearVersionTimelineState()
resetFilters()
loadAssets({ force: true }).catch((error) => {
errorMessage.value = error?.message || '资产数据加载失败,请稍后重试。'
})
})
function resetFilters() {
keyword.value = ''
selectedDomain.value = ''
selectedOwner.value = ''
selectedRiskLevel.value = ''
selectedStatus.value = ''
selectedRiskScenario.value = ''
selectedOnlineState.value = ''
selectedEnabledState.value = ''
activeFilterPopover.value = ''
}
function handleAuditEmptyAction() {
if (!currentAssets.value.length || !activeFilterTokens.value.length) {
loadAssets({ force: true }).catch(() => {})
return
}
resetFilters()
}
function toggleFilterPopover(name) {
activeFilterPopover.value = activeFilterPopover.value === name ? '' : name
}
function closeFilterPopover() {
activeFilterPopover.value = ''
}
function selectFilter(name, value) {
if (name === 'domain') {
selectedDomain.value = value
}
if (name === 'owner') {
selectedOwner.value = value
}
if (name === 'riskLevel') {
selectedRiskLevel.value = value
}
if (name === 'status') {
selectedStatus.value = value
}
if (name === 'riskScenario') {
selectedRiskScenario.value = value
}
if (name === 'online') {
selectedOnlineState.value = value
}
if (name === 'enabled') {
selectedEnabledState.value = value
}
closeFilterPopover()
}
function handleDocumentClick(event) {
const target = event.target
if (!(target instanceof Element)) {
closeFilterPopover()
return
}
if (!target.closest('.picker-filter')) {
closeFilterPopover()
}
}
function resolveActor() {
return currentUser.value?.name || currentUser.value?.username || 'system'
}
function openAssetDetail(asset) {
if (asset?.usesJsonRiskRule && asset.statusValue === 'generating') {
toast('规则仍在后台生成中,生成完成后才能进入详情。')
return
}
destroySpreadsheetOnlyOfficeEditor()
spreadsheetOnlyOfficeError.value = ''
spreadsheetOnlyOfficeLoading.value = false
if (asset?.isPreviewMock) {
selectedSkill.value = buildPreviewRuleDetail()
detailError.value = ''
detailLoading.value = false
clearVersionTimelineState()
return
}
const opensSpreadsheetRule = Boolean(asset?.usesSpreadsheetRule)
selectedSkill.value = {
...asset,
configJson: {},
isPreviewMock: false,
usesSpreadsheetRule: opensSpreadsheetRule,
usesJsonRiskRule: Boolean(asset?.usesJsonRiskRule),
riskRuleJsonText: '{}',
riskRuleSummary: null,
riskRuleDescription: '',
riskRuleSourceRef: '',
ruleDocument: asset?.ruleDocument || null,
scenarioList: [],
fields: [],
promptSections: [],
outputRules: [],
tests: [],
triggers: [],
tools: [],
history: [],
markdownContent: '',
runtimeRuleText: '',
ruleTemplateKey: '',
ruleTemplateLabel: '',
runtimeKind: 'policy_rule_draft',
displayVersion: asset.version,
displayVersionChangeNote: '无版本说明',
loading: !opensSpreadsheetRule,
reviewStatusLabel: opensSpreadsheetRule ? '' : '加载中',
reviewStatusTone: 'draft'
}
clearVersionTimelineState()
if (opensSpreadsheetRule) {
loadSpreadsheetChangeRecords(asset.id).catch(() => {})
}
loadSelectedAssetDetail(asset.id).catch(() => {})
}
function closeDetail() {
destroySpreadsheetOnlyOfficeEditor()
spreadsheetOnlyOfficeError.value = ''
spreadsheetOnlyOfficeLoading.value = false
selectedSkill.value = null
detailError.value = ''
detailLoading.value = false
clearVersionTimelineState()
resetRiskRuleActionDialogs()
}
onMounted(() => {
document.addEventListener('click', handleDocumentClick)
loadAssets({ force: true }).catch(() => {})
loadRuns().catch(() => {})
})
onBeforeUnmount(() => {
destroySpreadsheetOnlyOfficeEditor()
stopAllRiskRuleGenerationPolls()
document.removeEventListener('click', handleDocumentClick)
})
return {
tabs,
activeType,
activeTabLabel,
selectedSkill,
versionSwitchTarget,
keyword,
createButtonLabel,
hintText,
searchPlaceholder,
tableColumns,
showRuntimeColumn,
showVersionColumn,
showMetricColumn,
showStatusColumn,
showOnlineColumn,
showEnabledColumn,
visibleSkills,
auditEmptyState,
loading,
errorMessage,
detailLoading,
detailError,
selectedDomain,
selectedOwner,
selectedRiskLevel,
selectedStatus,
selectedRiskScenario,
selectedOnlineState,
selectedEnabledState,
selectedDomainLabel,
selectedOwnerLabel,
selectedRiskLevelLabel,
selectedStatusLabel,
selectedRiskScenarioLabel,
selectedOnlineStateLabel,
selectedEnabledStateLabel,
showRiskScenarioFilter,
showOwnerFilter,
showRiskLevelFilter,
showStatusFilter,
showOnlineFilter,
showEnabledFilter,
domainOptions,
ownerOptions,
riskLevelOptions,
statusOptions: STATUS_OPTIONS,
riskScenarioOptions: RISK_SCENARIO_OPTIONS,
onlineStateOptions: ONLINE_STATE_OPTIONS,
enabledStateOptions: ENABLED_STATE_OPTIONS,
activeFilterPopover,
activeFilterTokens,
canManageSelected,
canEditSelected,
canCreateRiskRule,
canOpenRiskRuleTest,
canDeleteRiskRule,
canOpenRiskRuleReviewSubmit,
canSubmitRiskRuleReview,
canReturnRiskRule,
canPublishRiskRule,
canToggleRiskRuleEnabled,
riskRuleTestPassed,
riskRuleInReview,
canSubmitReview,
hasReviewSubmitReviewers,
canReviewSelected,
canEditMarkdown,
canUploadSpreadsheet,
canDownloadSpreadsheet,
canEditSpreadsheetInline,
canActivateSelected,
activateBlockedReason,
selectedSkillIsRule,
selectedSkillUsesSpreadsheet,
selectedSkillUsesJsonRisk,
selectedSpreadsheetFileName,
selectedVersionTimelineItems,
selectedSpreadsheetChangeRecords,
detailBusy,
actionState,
reviewSubmitOpen,
reviewSubmitVersion,
reviewSubmitReviewer,
reviewSubmitReviewerLoading,
reviewSubmitReviewerOptions,
riskRuleAttachmentOptions,
riskRuleCreateOpen,
riskRuleCreateForm,
riskRuleCreateBusy,
riskRuleTestOpen,
riskRuleDeleteOpen,
riskRuleReturnOpen,
riskRulePublishOpen,
riskRuleReturnNote,
riskRuleEditOpen,
riskRuleEditMode,
riskRuleEditForm,
riskRuleBusinessStageOptions: RISK_RULE_BUSINESS_STAGE_OPTIONS,
riskRuleExpenseCategoryOptions: RISK_RULE_EXPENSE_CATEGORY_OPTIONS,
showReviewNote,
spreadsheetUploadInput,
spreadsheetOnlyOfficeLoading,
spreadsheetOnlyOfficeError,
spreadsheetOnlyOfficeReady,
spreadsheetOnlyOfficeHostId,
versionTimelineOpen,
versionTimelineLoading,
versionTimelineError,
spreadsheetChangeDetailOpen,
selectedSpreadsheetChangeRecord,
selectedSpreadsheetChangeSheetRows,
selectedSpreadsheetChangeCellRows,
openAssetDetail,
closeDetail,
resetFilters,
handleAuditEmptyAction,
toggleFilterPopover,
selectFilter,
closeFilterPopover,
openRiskRuleCreateDialog,
closeRiskRuleCreateDialog,
submitRiskRuleCreate,
openVersionSwitch: openVersionSwitchInState,
cancelVersionSwitch: cancelVersionSwitchInState,
confirmVersionSwitch: confirmVersionSwitchInState,
saveRuleMarkdown,
saveRuleRuntimeJson,
saveRiskRuleJson,
formatRiskRuleJson,
downloadRiskRuleJson,
triggerSpreadsheetUpload,
downloadSpreadsheetFile,
handleSpreadsheetFileInput,
reviewSelectedRule,
openSubmitReviewDialog,
closeSubmitReviewDialog,
submitSelectedRuleForReview,
openRiskRuleTestDialog,
closeRiskRuleTestDialog,
handleRiskRuleReportSaved,
openRiskRuleEditDialog,
closeRiskRuleEditDialog,
submitRiskRuleEdit,
openDeleteRiskRuleDialog,
closeDeleteRiskRuleDialog,
deleteSelectedRiskRule,
openReturnRiskRuleDialog,
closeReturnRiskRuleDialog,
returnSelectedRiskRule,
openPublishRiskRuleDialog,
closePublishRiskRuleDialog,
publishSelectedRiskRule,
toggleSelectedRiskRuleEnabled,
activateSelectedRule,
restoreSelectedVersion,
openVersionTimeline: openVersionTimelineInState,
closeVersionTimeline: closeVersionTimelineInState,
openSpreadsheetChangeDetail,
closeSpreadsheetChangeDetail,
loadAssets
}
}
}