diff --git a/cookbook/forms.py b/cookbook/forms.py index 7179c2c4f..028410796 100644 --- a/cookbook/forms.py +++ b/cookbook/forms.py @@ -502,6 +502,8 @@ class ShoppingPreferenceForm(forms.ModelForm): 'filter_to_supermarket': _('Filter shopping list to only include supermarket categories.'), 'shopping_recent_days': _('Days of recent shopping list entries to display.'), 'csv_delim': _('Delimiter to use for CSV exports.'), + 'csv_prefix': _('Prefix to add when copying list to the clipboard.'), + } labels = { 'shopping_share': _('Share Shopping List'), @@ -513,6 +515,7 @@ class ShoppingPreferenceForm(forms.ModelForm): 'filter_to_supermarket': _('Filter to Supermarket'), 'shopping_recent_days': _('Recent Days'), 'csv_delim': _('CSV Delimiter'), + "csv_prefix_label": _("List Prefix") } widgets = { diff --git a/cookbook/migrations/0162_userpreference_csv_delim.py b/cookbook/migrations/0162_userpreference_csv_delim.py index e296ba952..028eb6be5 100644 --- a/cookbook/migrations/0162_userpreference_csv_delim.py +++ b/cookbook/migrations/0162_userpreference_csv_delim.py @@ -15,4 +15,9 @@ class Migration(migrations.Migration): name='csv_delim', field=models.CharField(default=',', max_length=2), ), + migrations.AddField( + model_name='userpreference', + name='csv_prefix', + field=models.CharField(blank=True, max_length=3), + ), ] diff --git a/cookbook/models.py b/cookbook/models.py index 77affc5d3..e1c339bdf 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -334,6 +334,7 @@ class UserPreference(models.Model, PermissionModelMixin): default_delay = models.DecimalField(default=4, max_digits=8, decimal_places=4) shopping_recent_days = models.PositiveIntegerField(default=7) csv_delim = models.CharField(max_length=2, default=",") + csv_prefix = models.CharField(max_length=3, blank=True,) created_at = models.DateTimeField(auto_now_add=True) space = models.ForeignKey(Space, on_delete=models.CASCADE, null=True) diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 3401d2173..0da7f87b8 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -175,7 +175,7 @@ class UserPreferenceSerializer(serializers.ModelSerializer): 'user', 'theme', 'nav_color', 'default_unit', 'default_page', 'use_kj', 'search_style', 'show_recent', 'plan_share', 'ingredient_decimals', 'comments', 'shopping_auto_sync', 'mealplan_autoadd_shopping', 'food_ignore_default', 'default_delay', - 'mealplan_autoinclude_related', 'mealplan_autoexclude_onhand', 'shopping_share', 'shopping_recent_days', 'csv_delim' + 'mealplan_autoinclude_related', 'mealplan_autoexclude_onhand', 'shopping_share', 'shopping_recent_days', 'csv_delim', 'csv_prefix' ) read_only_fields = ['user'] diff --git a/cookbook/views/views.py b/cookbook/views/views.py index 2252acc15..ec1f61bcd 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -388,6 +388,8 @@ def user_settings(request): up.filter_to_supermarket = shopping_form.cleaned_data['filter_to_supermarket'] up.default_delay = shopping_form.cleaned_data['default_delay'] up.shopping_recent_days = shopping_form.cleaned_data['shopping_recent_days'] + up.csv_delim = shopping_form.cleaned_data['csv_delim'] + up.csv_prefix = shopping_form.cleaned_data['csv_prefix'] if up.shopping_auto_sync < settings.SHOPPING_MIN_AUTOSYNC_INTERVAL: up.shopping_auto_sync = settings.SHOPPING_MIN_AUTOSYNC_INTERVAL up.save() diff --git a/vue/src/apps/ShoppingListView/ShoppingListView.vue b/vue/src/apps/ShoppingListView/ShoppingListView.vue index f71063e8f..22cc9640e 100644 --- a/vue/src/apps/ShoppingListView/ShoppingListView.vue +++ b/vue/src/apps/ShoppingListView/ShoppingListView.vue @@ -6,19 +6,18 @@ - - + + - - + + @@ -360,6 +359,19 @@ +
+
{{ $t("csv_prefix_label") }}
+
+ +
+
+
+
+ + {{ $t("csv_prefix_help") }} + +
+
@@ -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) diff --git a/vue/src/components/Buttons/CopyToClipboard.vue b/vue/src/components/Buttons/CopyToClipboard.vue new file mode 100644 index 000000000..cb64987eb --- /dev/null +++ b/vue/src/components/Buttons/CopyToClipboard.vue @@ -0,0 +1,62 @@ + + + diff --git a/vue/src/locales/en.json b/vue/src/locales/en.json index 7b909ca16..05579373f 100644 --- a/vue/src/locales/en.json +++ b/vue/src/locales/en.json @@ -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" }