copy shopping as markdown

This commit is contained in:
smilerz
2021-12-02 08:19:41 -06:00
parent 903a721a1d
commit ca93920f04
8 changed files with 102 additions and 11 deletions

View File

@ -6,19 +6,18 @@
<b-button variant="link" class="px-0">
<i class="btn fas fa-plus-circle fa-lg px-0" @click="entrymode = !entrymode" :class="entrymode ? 'text-success' : 'text-muted'" />
</b-button>
<b-button variant="link" class="px-0">
<i class="fas fa-download fa-lg nav-link dropdown-toggle text-muted px-0" id="downloadShoppingLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<b-button variant="link" class="px-1">
<i class="fas fa-download fa-lg nav-link dropdown-toggle text-muted px-1" id="downloadShoppingLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"></i>
<div class="dropdown-menu dropdown-menu-center" aria-labelledby="downloadShoppingLink">
<a class="dropdown-item disabled" @click="download('CSV')"><i class="fas fa-file-import"></i> {{ $t("Download csv") }}</a>
<DownloadPDF dom="#shoppinglist" name="shopping.pdf" :label="$t('download_pdf')" icon="far fa-file-pdf" />
<DownloadCSV :items="csvData" :delim="settings.csv_delim" name="shopping.csv" :label="$t('download_csv')" icon="fas fa-file-csv" />
<a class="dropdown-item disabled" @click="download('clipboard')"><i class="fas fa-plus"></i> {{ $t("copy to clipboard") }}</a>
<a class="dropdown-item disabled" @click="download('markdown')"><i class="fas fa-plus"></i> {{ $t("copy as markdown") }}</a>
<CopyToClipboard :items="csvData" :settings="settings" :label="$t('copy_to_clipboard')" icon="fas fa-clipboard-list" />
<CopyToClipboard :items="csvData" :settings="settings" format="table" :label="$t('copy_markdown_table')" icon="fab fa-markdown" />
</div>
</b-button>
<b-button variant="link" id="id_filters_button" class="px-0">
<i class="btn fas fa-filter text-decoration-none fa-lg px-0" :class="filterApplied ? 'text-danger' : 'text-muted'" />
<b-button variant="link" id="id_filters_button" class="px-1">
<i class="btn fas fa-filter text-decoration-none fa-lg px-1" :class="filterApplied ? 'text-danger' : 'text-muted'" />
</b-button>
</div>
</div>
@ -360,6 +359,19 @@
</em>
</div>
</div>
<div class="row">
<div class="col col-md-6">{{ $t("csv_prefix_label") }}</div>
<div class="col col-md-6 text-right">
<input type="string" size="sm" v-model="settings.csv_prefix" @change="saveSettings" />
</div>
</div>
<div class="row sm mb-3">
<div class="col">
<em class="small text-muted">
{{ $t("csv_prefix_help") }}
</em>
</div>
</div>
</b-card>
</div>
</div>
@ -466,6 +478,7 @@ import ContextMenuItem from "@/components/ContextMenu/ContextMenuItem"
import ShoppingLineItem from "@/components/ShoppingLineItem"
import DownloadPDF from "@/components/Buttons/DownloadPDF"
import DownloadCSV from "@/components/Buttons/DownloadCSV"
import CopyToClipboard from "@/components/Buttons/CopyToClipboard"
import GenericMultiselect from "@/components/GenericMultiselect"
import GenericPill from "@/components/GenericPill"
import LookupInput from "@/components/Modals/LookupInput"
@ -480,7 +493,7 @@ Vue.use(BootstrapVue)
export default {
name: "ShoppingListView",
mixins: [ApiMixin],
components: { ContextMenu, ContextMenuItem, ShoppingLineItem, GenericMultiselect, GenericPill, draggable, LookupInput, DownloadPDF, DownloadCSV },
components: { ContextMenu, ContextMenuItem, ShoppingLineItem, GenericMultiselect, GenericPill, draggable, LookupInput, DownloadPDF, DownloadCSV, CopyToClipboard },
data() {
return {
@ -504,6 +517,7 @@ export default {
filter_to_supermarket: false,
shopping_recent_days: 7,
csv_delim: ",",
csv_prefix: undefined,
},
new_supermarket: { entrymode: false, value: undefined, editmode: undefined },
new_category: { entrymode: false, value: undefined },
@ -665,7 +679,6 @@ export default {
this.settings = getUserPreference()
this.delay = this.settings.default_delay || 4
this.delim = this.settings.csv_delim || ","
this.supermarket_categories_only = this.settings.filter_to_supermarket
if (this.settings.shopping_auto_sync) {
window.addEventListener("online", this.updateOnlineStatus)

View File

@ -0,0 +1,62 @@
<template>
<div>
<a v-if="!button" class="dropdown-item" @click="clipboard"><i :class="icon"></i> {{ label }}</a>
<b-button v-if="button" @click="clipboard">{{ label }}</b-button>
</div>
</template>
<script>
import { makeToast } from "@/utils/utils"
export default {
name: "CopyToClipboard",
props: {
items: { type: Array },
icon: { type: String },
label: { type: String },
button: { type: Boolean, default: false },
settings: { type: Object },
format: { type: String, default: "delim" },
},
methods: {
clipboard: function () {
let text = ""
switch (this.format) {
case "delim":
text = this.delimited()
break
case "table":
text = this.table()
break
}
navigator.clipboard.writeText(text).then(makeToast(this.$t("Success"), this.$t("SuccessClipboard"), "success"))
},
delimited: function () {
let csvContent = ""
let delim = this.settings.csv_delim || ","
let prefix = this.settings.csv_prefix || ""
csvContent += [prefix + Object.keys(this.items[0]).join(delim), ...this.items.map((x) => prefix + Object.values(x).join(delim))].join("\n").replace(/(^\[)|(\]$)/gm, "")
return csvContent
},
table: function () {
let table = ""
let delim = "|"
table += [
delim + Object.keys(this.items[0]).join(delim) + delim,
delim +
Object.keys(this.items[0])
.map((x) => {
return ":---"
})
.join(delim) +
delim,
...this.items.map((x) => delim + Object.values(x).join(delim) + delim),
]
.join("\n")
.replace(/(^\[)|(\]$)/gm, "")
return table
},
},
}
</script>

View File

@ -269,5 +269,10 @@
"download_pdf": "Download PDF",
"download_csv": "Download CSV",
"csv_delim_help": "Delimiter to use for CSV exports.",
"csv_delim_label": "CSV Delimiter"
"csv_delim_label": "CSV Delimiter",
"SuccessClipboard": "Shopping list copied to clipboard",
"copy_to_clipboard": "Copy to Clipboard",
"csv_prefix_help": "Prefix to add when copying list to the clipboard.",
"csv_prefix_label": "List Prefix",
"copy_markdown_table": "Copy as Markdown Table"
}