feat(frontend): stream description editing and proper md rendering and sanitisation
This commit is contained in:
Generated
+10
@@ -6215,6 +6215,11 @@
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"dompurify": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.2.4.tgz",
|
||||
"integrity": "sha512-jE21SelIgWrGKoXGfGPA524Zt1IJFBnktwfFMHDlEYRx5FZOdc+4eEH9mkA6PuhExrq3HVpJnY8hMYUzAMl0OA=="
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
|
||||
@@ -9663,6 +9668,11 @@
|
||||
"object-visit": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"marked": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-1.2.6.tgz",
|
||||
"integrity": "sha512-7vVuSEZ8g/HH3hK/BH/+7u/NJj7x9VY4EHzujLDcqAQLiOUeFJYAsfSAyoWtR17lKrx7b08qyIno4lffwrzTaA=="
|
||||
},
|
||||
"md5.js": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
"@vuejs-community/vue-filter-date-parse": "^1.1.6",
|
||||
"core-js": "^3.8.1",
|
||||
"crypto-random-string": "^3.3.0",
|
||||
"dompurify": "^2.2.4",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"marked": "^1.2.6",
|
||||
"v-tooltip": "^2.0.3",
|
||||
"vue": "^2.6.12",
|
||||
"vue-apollo": "^3.0.5",
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<v-card class="pa-4" color="background2">
|
||||
<v-card-title class="subtitle-1">Edit Description</v-card-title>
|
||||
<v-card-text>
|
||||
<v-row>
|
||||
<v-col sm="12" md="6">
|
||||
<p>Markdown is enabled.</p>
|
||||
<v-textarea
|
||||
v-model="innerStreamDescription"
|
||||
auto-grow
|
||||
filled
|
||||
rows="10"
|
||||
style="font-size: 12px; line-height: 10px;"
|
||||
></v-textarea>
|
||||
</v-col>
|
||||
<v-col sm="12" md="6">
|
||||
<p>Preview</p>
|
||||
<div class="marked-preview" v-html="compiledMarkdown"></div>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<!-- <v-spacer></v-spacer> -->
|
||||
<v-btn @click.native="save">Save & Close</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</template>
|
||||
<script>
|
||||
import marked from "marked"
|
||||
import DOMPurify from "dompurify"
|
||||
import gql from "graphql-tag"
|
||||
|
||||
export default {
|
||||
props: {
|
||||
id: String,
|
||||
description: {
|
||||
type: String,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data: () => ({
|
||||
innerStreamDescription: null
|
||||
}),
|
||||
computed: {
|
||||
compiledMarkdown() {
|
||||
if (!this.innerStreamDescription) return ""
|
||||
let md = marked(this.innerStreamDescription)
|
||||
return DOMPurify.sanitize(md)
|
||||
},
|
||||
streamDescription: {
|
||||
get() {
|
||||
return this.innerStreamDescription
|
||||
},
|
||||
set(value) {
|
||||
this.innerStreamDescription = value
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.innerStreamDescription = this.description
|
||||
},
|
||||
methods: {
|
||||
async save() {
|
||||
try {
|
||||
this.$apollo.mutate({
|
||||
mutation: gql`
|
||||
mutation editDescription($input: StreamUpdateInput!) {
|
||||
streamUpdate(stream: $input)
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
input: {
|
||||
id: this.id,
|
||||
description: this.innerStreamDescription
|
||||
}
|
||||
}
|
||||
})
|
||||
this.$emit("close", this.innerStreamDescription)
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -11,10 +11,29 @@
|
||||
<v-row>
|
||||
<v-col cols="12" sm="12" lg="12">
|
||||
<v-card rounded="lg" class="pa-4" elevation="0" color="background2">
|
||||
<v-card-title>Description</v-card-title>
|
||||
<v-card-text>
|
||||
{{ stream.description }}
|
||||
<v-card-title v-if="!stream.description">
|
||||
Description
|
||||
</v-card-title>
|
||||
<v-card-text v-if="!stream.description">
|
||||
No description provided.
|
||||
</v-card-text>
|
||||
<v-card-text
|
||||
v-if="stream.description"
|
||||
class="marked-preview"
|
||||
v-html="compiledStreamDescription"
|
||||
></v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn small @click="dialogDescription = true">
|
||||
Edit Description
|
||||
</v-btn>
|
||||
<v-dialog v-model="dialogDescription">
|
||||
<stream-description-dialog
|
||||
:id="stream.id"
|
||||
:description="stream.description"
|
||||
@close="closeDescription"
|
||||
/>
|
||||
</v-dialog>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
|
||||
@@ -23,7 +42,7 @@
|
||||
<v-col cols="12" sm="12" lg="12">
|
||||
<v-card rounded="lg" class="pa-4" elevation="0" color="background2">
|
||||
<v-card-title>
|
||||
<v-icon class='mr-2'>mdi-source-branch</v-icon>
|
||||
<v-icon class="mr-2">mdi-source-branch</v-icon>
|
||||
Branches
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
@@ -41,14 +60,8 @@
|
||||
<v-list-item-title>
|
||||
<b>{{ item.name }}</b>
|
||||
|
||||
<v-chip outlined>
|
||||
<v-avatar
|
||||
size="10"
|
||||
left
|
||||
class="primary white--text"
|
||||
>
|
||||
{{ item.commits.totalCount }}
|
||||
</v-avatar>
|
||||
<v-chip small>
|
||||
{{ item.commits.totalCount }}
|
||||
commits
|
||||
</v-chip>
|
||||
</v-list-item-title>
|
||||
@@ -63,7 +76,7 @@
|
||||
</v-list-item>
|
||||
</template>
|
||||
</v-list>
|
||||
<v-btn block @click="newBranch">Create a new branch</v-btn>
|
||||
<v-btn small @click="newBranch">new branch</v-btn>
|
||||
<branch-dialog
|
||||
ref="branchDialog"
|
||||
:branches="branches"
|
||||
@@ -101,18 +114,27 @@
|
||||
</v-container>
|
||||
</template>
|
||||
<script>
|
||||
import marked from "marked"
|
||||
import DOMPurify from "dompurify"
|
||||
import gql from "graphql-tag"
|
||||
import SidebarStream from "../components/SidebarStream"
|
||||
import BranchDialog from "../components/dialogs/BranchDialog"
|
||||
import StreamDescriptionDialog from "../components/dialogs/StreamDescriptionDialog"
|
||||
import ListItemCommit from "../components/ListItemCommit"
|
||||
import streamQuery from "../graphql/stream.gql"
|
||||
import streamCommitsQuery from "../graphql/streamCommits.gql"
|
||||
|
||||
export default {
|
||||
name: "Stream",
|
||||
components: { SidebarStream, BranchDialog, ListItemCommit },
|
||||
components: {
|
||||
SidebarStream,
|
||||
BranchDialog,
|
||||
ListItemCommit,
|
||||
StreamDescriptionDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogDescription: false,
|
||||
selectedBranch: 0,
|
||||
stream: {
|
||||
id: null,
|
||||
@@ -153,6 +175,11 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
compiledStreamDescription() {
|
||||
if (!this.stream.description) return ""
|
||||
let md = marked(this.stream.description)
|
||||
return DOMPurify.sanitize(md)
|
||||
},
|
||||
branches() {
|
||||
//reverse without changing original array
|
||||
return this.stream.branches.items.slice().reverse()
|
||||
@@ -162,6 +189,10 @@ export default {
|
||||
this.$matomo && this.$matomo.trackPageView("streams/single")
|
||||
},
|
||||
methods: {
|
||||
closeDescription(newDescription) {
|
||||
this.stream.description = newDescription
|
||||
this.dialogDescription = false
|
||||
},
|
||||
newBranch() {
|
||||
this.$refs.branchDialog.open().then((dialog) => {
|
||||
if (!dialog.result) return
|
||||
|
||||
Reference in New Issue
Block a user