From 84afa8be85e511b7eabb9546a42df9fdbca930e7 Mon Sep 17 00:00:00 2001
From: Marc Vilanova
', '\n', text)
+ text = re.sub(r'
]*>', '', text)
+ text = re.sub(r'?[^>]+>', '', text)
+
+ # Clean up extra whitespace
+ text = re.sub(r'\n\s*\n\s*\n', '\n\n', text) # Multiple newlines to double
+ text = re.sub(r'[ \t]+', ' ', text) # Multiple spaces/tabs to single space
+ text = text.strip()
+
+ return text
def create_case_message(case: Case, channel_id: str) -> list[Block]:
@@ -142,11 +185,13 @@ def create_case_message(case: Case, channel_id: str) -> list[Block]:
]
)
elif case.status == CaseStatus.closed:
+ # Convert HTML resolution to plain text for Slack display
+ resolution_text = html_to_plain_text(case.resolution) if case.resolution else ""
blocks.extend(
[
Section(text=f"*Resolution reason* \n {case.resolution_reason}"),
Section(
- text=f"*Resolution description* \n {case.resolution}"[:MAX_SECTION_TEXT_LENGTH]
+ text=f"*Resolution description* \n {resolution_text}"[:MAX_SECTION_TEXT_LENGTH]
),
Actions(
elements=[
diff --git a/src/dispatch/static/dispatch/components.d.ts b/src/dispatch/static/dispatch/components.d.ts
index cd9ce5015d8e..b4e4bf790339 100644
--- a/src/dispatch/static/dispatch/components.d.ts
+++ b/src/dispatch/static/dispatch/components.d.ts
@@ -8,11 +8,9 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
AdminLayout: typeof import('./src/components/layouts/AdminLayout.vue')['default']
- AnimatedNumber: typeof import("./src/components/AnimatedNumber.vue")["default"]
AppDrawer: typeof import('./src/components/AppDrawer.vue')['default']
AppToolbar: typeof import('./src/components/AppToolbar.vue')['default']
AutoComplete: typeof import('./src/components/AutoComplete.vue')['default']
- Avatar: typeof import("./src/components/Avatar.vue")["default"]
BaseCombobox: typeof import('./src/components/BaseCombobox.vue')['default']
BasicLayout: typeof import('./src/components/layouts/BasicLayout.vue')['default']
ColorPickerInput: typeof import('./src/components/ColorPickerInput.vue')['default']
@@ -25,17 +23,15 @@ declare module '@vue/runtime-core' {
DMenu: typeof import('./src/components/DMenu.vue')['default']
DTooltip: typeof import('./src/components/DTooltip.vue')['default']
GenaiAnalysisDisplay: typeof import('./src/components/GenaiAnalysisDisplay.vue')['default']
+ HtmlRenderer: typeof import('./src/components/HtmlRenderer.vue')['default']
IconPickerInput: typeof import('./src/components/IconPickerInput.vue')['default']
InfoWidget: typeof import('./src/components/InfoWidget.vue')['default']
Loading: typeof import('./src/components/Loading.vue')['default']
LockButton: typeof import('./src/components/LockButton.vue')['default']
MonacoEditor: typeof import('./src/components/MonacoEditor.vue')['default']
NotificationSnackbarsWrapper: typeof import('./src/components/NotificationSnackbarsWrapper.vue')['default']
- PageHeader: typeof import("./src/components/PageHeader.vue")["default"]
- ParticipantAutoComplete: typeof import("./src/components/ParticipantAutoComplete.vue")["default"]
ParticipantSelect: typeof import('./src/components/ParticipantSelect.vue')['default']
PreciseDateTimePicker: typeof import('./src/components/PreciseDateTimePicker.vue')['default']
- ProjectAutoComplete: typeof import("./src/components/ProjectAutoComplete.vue")["default"]
Refresh: typeof import('./src/components/Refresh.vue')['default']
RichEditor: typeof import('./src/components/RichEditor.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
@@ -43,93 +39,6 @@ declare module '@vue/runtime-core' {
SavingState: typeof import('./src/components/SavingState.vue')['default']
SearchPopover: typeof import('./src/components/SearchPopover.vue')['default']
SettingsBreadcrumbs: typeof import('./src/components/SettingsBreadcrumbs.vue')['default']
- ShepherdStep: typeof import("./src/components/ShepherdStep.vue")["default"]
- ShpherdStep: typeof import("./src/components/ShpherdStep.vue")["default"]
StatWidget: typeof import('./src/components/StatWidget.vue')['default']
- SubjectLastUpdated: typeof import("./src/components/SubjectLastUpdated.vue")["default"]
- TimePicker: typeof import("./src/components/TimePicker.vue")["default"]
- VAlert: typeof import("vuetify/lib")["VAlert"]
- VApp: typeof import("vuetify/lib")["VApp"]
- VAppBar: typeof import("vuetify/lib")["VAppBar"]
- VAutocomplete: typeof import("vuetify/lib")["VAutocomplete"]
- VAvatar: typeof import("vuetify/lib")["VAvatar"]
- VBadge: typeof import("vuetify/lib")["VBadge"]
- VBottomSheet: typeof import("vuetify/lib")["VBottomSheet"]
- VBreadcrumbs: typeof import("vuetify/lib")["VBreadcrumbs"]
- VBreadcrumbsItem: typeof import("vuetify/lib")["VBreadcrumbsItem"]
- VBtn: typeof import("vuetify/lib")["VBtn"]
- VCard: typeof import("vuetify/lib")["VCard"]
- VCardActions: typeof import("vuetify/lib")["VCardActions"]
- VCardSubtitle: typeof import("vuetify/lib")["VCardSubtitle"]
- VCardText: typeof import("vuetify/lib")["VCardText"]
- VCardTitle: typeof import("vuetify/lib")["VCardTitle"]
- VCheckbox: typeof import("vuetify/lib")["VCheckbox"]
- VChip: typeof import("vuetify/lib")["VChip"]
- VChipGroup: typeof import("vuetify/lib")["VChipGroup"]
- VCol: typeof import("vuetify/lib")["VCol"]
- VColorPicker: typeof import("vuetify/lib")["VColorPicker"]
- VCombobox: typeof import("vuetify/lib")["VCombobox"]
- VContainer: typeof import("vuetify/lib")["VContainer"]
- VDataTable: typeof import("vuetify/lib")["VDataTable"]
- VDatePicker: typeof import("vuetify/lib")["VDatePicker"]
- VDialog: typeof import("vuetify/lib")["VDialog"]
- VDivider: typeof import("vuetify/lib")["VDivider"]
- VExpandTransition: typeof import("vuetify/lib")["VExpandTransition"]
- VExpansionPanel: typeof import("vuetify/lib")["VExpansionPanel"]
- VExpansionPanelContent: typeof import("vuetify/lib")["VExpansionPanelContent"]
- VExpansionPanelHeader: typeof import("vuetify/lib")["VExpansionPanelHeader"]
- VExpansionPanels: typeof import("vuetify/lib")["VExpansionPanels"]
- VFlex: typeof import("vuetify/lib")["VFlex"]
- VForm: typeof import("vuetify/lib")["VForm"]
- VHover: typeof import("vuetify/lib")["VHover"]
- VIcon: typeof import("vuetify/lib")["VIcon"]
- VItem: typeof import("vuetify/lib")["VItem"]
- VLayout: typeof import("vuetify/lib")["VLayout"]
- VLazy: typeof import("vuetify/lib")["VLazy"]
- VList: typeof import("vuetify/lib")["VList"]
- VListGroup: typeof import("vuetify/lib")["VListGroup"]
- VListItem: typeof import("vuetify/lib")["VListItem"]
- VListItemAction: typeof import("vuetify/lib")["VListItemAction"]
- VListItemAvatar: typeof import("vuetify/lib")["VListItemAvatar"]
- VListItemContent: typeof import("vuetify/lib")["VListItemContent"]
- VListItemGroup: typeof import("vuetify/lib")["VListItemGroup"]
- VListItemIcon: typeof import("vuetify/lib")["VListItemIcon"]
- VListItemSubtitle: typeof import("vuetify/lib")["VListItemSubtitle"]
- VListItemTitle: typeof import("vuetify/lib")["VListItemTitle"]
- VMain: typeof import("vuetify/lib")["VMain"]
- VMenu: typeof import("vuetify/lib")["VMenu"]
- VNavigationDrawer: typeof import("vuetify/lib")["VNavigationDrawer"]
- VProgressLinear: typeof import("vuetify/lib")["VProgressLinear"]
- VRadio: typeof import("vuetify/lib")["VRadio"]
- VRadioGroup: typeof import("vuetify/lib")["VRadioGroup"]
- VRow: typeof import("vuetify/lib")["VRow"]
- VSelect: typeof import("vuetify/lib")["VSelect"]
- VSheet: typeof import("vuetify/lib")["VSheet"]
- VSimpleCheckbox: typeof import("vuetify/lib")["VSimpleCheckbox"]
- VSnackbar: typeof import("vuetify/lib")["VSnackbar"]
- VSpacer: typeof import("vuetify/lib")["VSpacer"]
- VStepper: typeof import("vuetify/lib")["VStepper"]
- VStepperContent: typeof import("vuetify/lib")["VStepperContent"]
- VStepperHeader: typeof import("vuetify/lib")["VStepperHeader"]
- VStepperItems: typeof import("vuetify/lib")["VStepperItems"]
- VStepperStep: typeof import("vuetify/lib")["VStepperStep"]
- VSubheader: typeof import("vuetify/lib")["VSubheader"]
- VSwitch: typeof import("vuetify/lib")["VSwitch"]
- VSystemBar: typeof import("vuetify/lib")["VSystemBar"]
- VTab: typeof import("vuetify/lib")["VTab"]
- VTabItem: typeof import("vuetify/lib")["VTabItem"]
- VTabs: typeof import("vuetify/lib")["VTabs"]
- VTabsItems: typeof import("vuetify/lib")["VTabsItems"]
- VTextarea: typeof import("vuetify/lib")["VTextarea"]
- VTextArea: typeof import("vuetify/lib")["VTextArea"]
- VTextField: typeof import("vuetify/lib")["VTextField"]
- VTimeline: typeof import("vuetify/lib")["VTimeline"]
- VTimelineItem: typeof import("vuetify/lib")["VTimelineItem"]
- VTimePicker: typeof import("vuetify/lib")["VTimePicker"]
- VToolbarItems: typeof import("vuetify/lib")["VToolbarItems"]
- VToolbarTitle: typeof import("vuetify/lib")["VToolbarTitle"]
- VTooltip: typeof import("vuetify/lib")["VTooltip"]
- VWindow: typeof import("vuetify/lib")["VWindow"]
- VWindowItem: typeof import("vuetify/lib")["VWindowItem"]
}
}
diff --git a/src/dispatch/static/dispatch/src/case/CaseAttributesDrawer.vue b/src/dispatch/static/dispatch/src/case/CaseAttributesDrawer.vue
index 3ce037f86e5b..631dc467bb9e 100644
--- a/src/dispatch/static/dispatch/src/case/CaseAttributesDrawer.vue
+++ b/src/dispatch/static/dispatch/src/case/CaseAttributesDrawer.vue
@@ -11,6 +11,7 @@ import DTooltip from "@/components/DTooltip.vue"
import ParticipantSearchPopover from "@/participant/ParticipantSearchPopover.vue"
import ProjectSearchPopover from "@/project/ProjectSearchPopover.vue"
import TagSearchPopover from "@/tag/TagSearchPopover.vue"
+import RichEditor from "@/components/RichEditor.vue"
import { useSavingState } from "@/composables/useSavingState"
// Define the props
diff --git a/src/dispatch/static/dispatch/src/case/ClosedDialog.vue b/src/dispatch/static/dispatch/src/case/ClosedDialog.vue
index 660765180fd1..4e89e9ddc2ef 100644
--- a/src/dispatch/static/dispatch/src/case/ClosedDialog.vue
+++ b/src/dispatch/static/dispatch/src/case/ClosedDialog.vue
@@ -19,11 +19,18 @@
/>