-
Notifications
You must be signed in to change notification settings - Fork 518
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Moving and renaming various components
- Loading branch information
Showing
3 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
src/dispatch/static/dispatch/src/case/CaseTimelineTabV1.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<template> | ||
<v-container> | ||
<v-row justify="end"> | ||
<v-switch v-model="showDetails" label="Show details" /> | ||
<v-btn | ||
color="secondary" | ||
class="ml-2 mr-2 mt-3" | ||
@click="exportToCSV()" | ||
:loading="exportLoading" | ||
> | ||
Export | ||
</v-btn> | ||
</v-row> | ||
<template v-if="events && events.length"> | ||
<v-timeline density="compact" clipped> | ||
<v-timeline-item hide-dot> | ||
<v-col class="text-right text-caption">(times in UTC)</v-col> | ||
</v-timeline-item> | ||
<v-timeline-item | ||
v-for="event in sortedEvents" | ||
:key="event.id" | ||
class="mb-4" | ||
dot-color="blue" | ||
size="small" | ||
> | ||
<v-row justify="space-between"> | ||
<v-col cols="7"> | ||
{{ event.description }} | ||
<transition-group name="slide" v-if="showDetails"> | ||
<template v-for="(value, key) in event.details" :key="key"> | ||
<v-card> | ||
<v-card-title class="text-subtitle-1"> | ||
{{ snakeToCamel(key) }} | ||
</v-card-title> | ||
<v-card-text>{{ value }}</v-card-text> | ||
</v-card> | ||
</template> | ||
</transition-group> | ||
<div class="text-caption"> | ||
{{ event.source }} | ||
</div> | ||
</v-col> | ||
<v-col class="text-right" cols="5"> | ||
<v-tooltip location="bottom"> | ||
<template #activator="{ props }"> | ||
<span v-bind="props" class="wavy-underline">{{ | ||
formatToUTC(event.started_at) | ||
}}</span> | ||
</template> | ||
<span class="pre-formatted">{{ formatToTimeZones(event.started_at) }}</span> | ||
</v-tooltip> | ||
</v-col> | ||
</v-row> | ||
</v-timeline-item> | ||
</v-timeline> | ||
</template> | ||
<div v-else> | ||
<p class="text-center">No timeline data available.</p> | ||
</div> | ||
</v-container> | ||
</template> | ||
|
||
<script> | ||
import { mapFields } from "vuex-map-fields" | ||
import Util from "@/util" | ||
import { snakeToCamel, formatToUTC, formatToTimeZones } from "@/filters" | ||
export default { | ||
name: "CaseTimelineTabOld", | ||
data() { | ||
return { | ||
showDetails: false, | ||
exportLoading: false, | ||
} | ||
}, | ||
setup() { | ||
return { snakeToCamel, formatToUTC, formatToTimeZones } | ||
}, | ||
computed: { | ||
...mapFields("case_management", ["selected.events", "selected.name"]), | ||
sortedEvents: function () { | ||
return this.events.slice().sort((a, b) => new Date(a.started_at) - new Date(b.started_at)) | ||
}, | ||
}, | ||
methods: { | ||
exportToCSV() { | ||
this.exportLoading = true | ||
let items = this.sortedEvents | ||
Util.exportCSV(items, this.name + "-timeline-export.csv") | ||
this.exportLoading = false | ||
}, | ||
}, | ||
} | ||
</script> | ||
|
||
<style scoped src="@/styles/timeline.css" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!-- EscalateButton.vue --> | ||
<template> | ||
<div> | ||
<v-btn variant="plain" :ripple="false" @click="showDialog"> | ||
<v-icon>mdi-fire</v-icon> | ||
</v-btn> | ||
<CaseEscalateDialog /> | ||
</div> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import { useStore } from "vuex" | ||
import CaseEscalateDialog from "@/case/EscalateDialog.vue" | ||
|
||
const store = useStore() | ||
|
||
const showDialog = () => { | ||
const caseDetails = store.state.case_management.selected | ||
store.dispatch("case_management/showEscalateDialog", caseDetails) | ||
} | ||
</script> |
104 changes: 104 additions & 0 deletions
104
src/dispatch/static/dispatch/src/components/RichEditor.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
<template> | ||
<div> | ||
<editor-content :editor="editor" @keydown.enter.prevent /> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { ref, onMounted, onBeforeUnmount, watch } from "vue" | ||
import { Editor, EditorContent } from "@tiptap/vue-3" | ||
import StarterKit from "@tiptap/starter-kit" | ||
import CaseApi from "@/case/api" | ||
import { useStore } from "vuex" | ||
const props = defineProps({ | ||
modelValue: { | ||
type: String, | ||
default: "", | ||
}, | ||
title: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
description: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
resolution: { | ||
type: Boolean, | ||
default: false, | ||
}, | ||
}) | ||
const store = useStore() | ||
const editor = ref(null) | ||
const plainTextValue = ref("") | ||
watch( | ||
() => props.modelValue, | ||
(value) => { | ||
const isSame = editor.value?.getHTML() === value | ||
if (isSame) { | ||
return | ||
} | ||
if (props.title) { | ||
editor.value?.chain().focus().setContent(`<h2>${value}</h2>`, false).run() | ||
} else { | ||
editor.value?.chain().focus().setContent(`${value}`, false).run() | ||
} | ||
} | ||
) | ||
onMounted(() => { | ||
editor.value = new Editor({ | ||
extensions: [StarterKit.configure({ heading: { levels: [2] } })], | ||
content: props.modelValue, | ||
onUpdate: () => { | ||
let content = editor.value?.getHTML() | ||
// remove the HTML tags | ||
plainTextValue.value = content.replace(/<\/?[^>]+(>|$)/g, "") | ||
// Get the case details from the Vuex store | ||
const caseDetails = store.state.case_management.selected | ||
// Update the title value | ||
if (props.title) { | ||
caseDetails.title = plainTextValue.value | ||
} | ||
if (props.description) { | ||
caseDetails.description = plainTextValue.value | ||
} | ||
if (props.resolution) { | ||
caseDetails.resolution = plainTextValue.value | ||
} | ||
// Save the changes | ||
CaseApi.update(caseDetails.id, caseDetails) | ||
}, | ||
keyboardShortcuts: { | ||
Enter: () => {}, // Override Enter key to do nothing | ||
}, | ||
}) | ||
}) | ||
onBeforeUnmount(() => { | ||
editor.value?.destroy() | ||
}) | ||
// Expose plainTextValue for parent component to use | ||
defineExpose({ plainTextValue }) | ||
</script> | ||
<style lang="scss"> | ||
/* Basic editor styles */ | ||
.tiptap { | ||
> * + * { | ||
margin-top: 0.75em; | ||
} | ||
} | ||
input[type="checkbox"] { | ||
margin-right: 4px; | ||
} | ||
</style> |