mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-10-27 16:24:31 -04:00 
			
		
		
		
	feat: check all in shopping list view (#3786)
Co-authored-by: Olly Welch <mail@ollywelch.com>
This commit is contained in:
		| @@ -809,7 +809,10 @@ | |||||||
|     "linked-recipes-count": "No Linked Recipes|One Linked Recipe|{count} Linked Recipes", |     "linked-recipes-count": "No Linked Recipes|One Linked Recipe|{count} Linked Recipes", | ||||||
|     "items-checked-count": "No items checked|One item checked|{count} items checked", |     "items-checked-count": "No items checked|One item checked|{count} items checked", | ||||||
|     "no-label": "No Label", |     "no-label": "No Label", | ||||||
|     "completed-on": "Completed on {date}" |     "completed-on": "Completed on {date}", | ||||||
|  |     "are-you-sure-you-want-to-check-all-items": "Are you sure you want to check all items?", | ||||||
|  |     "are-you-sure-you-want-to-uncheck-all-items": "Are you sure you want to uncheck all items?", | ||||||
|  |     "are-you-sure-you-want-to-delete-checked-items": "Are you sure you want to delete all checked items?" | ||||||
|   }, |   }, | ||||||
|   "sidebar": { |   "sidebar": { | ||||||
|     "all-recipes": "All Recipes", |     "all-recipes": "All Recipes", | ||||||
|   | |||||||
| @@ -1,5 +1,17 @@ | |||||||
| <template> | <template> | ||||||
|   <v-container v-if="shoppingList" class="md-container"> |   <v-container v-if="shoppingList" class="md-container"> | ||||||
|  |     <BaseDialog v-model="checkAllDialog" :title="$tc('general.confirm')" @confirm="checkAll"> | ||||||
|  |       <v-card-text>{{ $t('shopping-list.are-you-sure-you-want-to-check-all-items') }}</v-card-text> | ||||||
|  |     </BaseDialog> | ||||||
|  |  | ||||||
|  |     <BaseDialog v-model="uncheckAllDialog" :title="$tc('general.confirm')" @confirm="uncheckAll"> | ||||||
|  |       <v-card-text>{{ $t('shopping-list.are-you-sure-you-want-to-uncheck-all-items') }}</v-card-text> | ||||||
|  |     </BaseDialog> | ||||||
|  |  | ||||||
|  |     <BaseDialog v-model="deleteCheckedDialog" :title="$tc('general.confirm')" @confirm="deleteChecked"> | ||||||
|  |       <v-card-text>{{ $t('shopping-list.are-you-sure-you-want-to-delete-checked-items') }}</v-card-text> | ||||||
|  |     </BaseDialog> | ||||||
|  |  | ||||||
|     <BasePageTitle divider> |     <BasePageTitle divider> | ||||||
|       <template #header> |       <template #header> | ||||||
|         <v-container> |         <v-container> | ||||||
| @@ -164,10 +176,16 @@ | |||||||
|               text: $tc('shopping-list.uncheck-all-items'), |               text: $tc('shopping-list.uncheck-all-items'), | ||||||
|               event: 'uncheck', |               event: 'uncheck', | ||||||
|             }, |             }, | ||||||
|  |             { | ||||||
|  |               icon: $globals.icons.checkboxOutline, | ||||||
|  |               text: $tc('shopping-list.check-all-items'), | ||||||
|  |               event: 'check', | ||||||
|  |             }, | ||||||
|           ]" |           ]" | ||||||
|           @edit="edit = true" |           @edit="edit = true" | ||||||
|           @delete="deleteChecked" |           @delete="openDeleteChecked" | ||||||
|           @uncheck="uncheckAll" |           @uncheck="openUncheckAll" | ||||||
|  |           @check="openCheckAll" | ||||||
|           @sort-by-labels="sortByLabels" |           @sort-by-labels="sortByLabels" | ||||||
|           @copy-plain="copyListItems('plain')" |           @copy-plain="copyListItems('plain')" | ||||||
|           @copy-markdown="copyListItems('markdown')" |           @copy-markdown="copyListItems('markdown')" | ||||||
| @@ -256,7 +274,7 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import draggable from "vuedraggable"; | import draggable from "vuedraggable"; | ||||||
|  |  | ||||||
| import { defineComponent, useRoute, computed, ref, onUnmounted, useContext } from "@nuxtjs/composition-api"; | import { defineComponent, useRoute, computed, ref, toRefs, onUnmounted, useContext, reactive } from "@nuxtjs/composition-api"; | ||||||
| import { useIdle, useToggle } from "@vueuse/core"; | import { useIdle, useToggle } from "@vueuse/core"; | ||||||
| import { useCopyList } from "~/composables/use-copy"; | import { useCopyList } from "~/composables/use-copy"; | ||||||
| import { useUserApi } from "~/composables/api"; | import { useUserApi } from "~/composables/api"; | ||||||
| @@ -303,6 +321,12 @@ export default defineComponent({ | |||||||
|     const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); |     const groupSlug = computed(() => route.value.params.groupSlug || $auth.user?.groupSlug || ""); | ||||||
|     const id = route.value.params.id; |     const id = route.value.params.id; | ||||||
|  |  | ||||||
|  |     const state = reactive({ | ||||||
|  |       checkAllDialog: false, | ||||||
|  |       uncheckAllDialog: false, | ||||||
|  |       deleteCheckedDialog: false, | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     // =============================================================== |     // =============================================================== | ||||||
|     // Shopping List Actions |     // Shopping List Actions | ||||||
|  |  | ||||||
| @@ -448,8 +472,34 @@ export default defineComponent({ | |||||||
|  |  | ||||||
|     // ===================================== |     // ===================================== | ||||||
|     // Check / Uncheck All |     // Check / Uncheck All | ||||||
|  |     function openCheckAll() { | ||||||
|  |       if (shoppingList.value?.listItems?.some((item) => !item.checked)) { | ||||||
|  |         state.checkAllDialog = true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function checkAll() { | ||||||
|  |       state.checkAllDialog = false; | ||||||
|  |       let hasChanged = false; | ||||||
|  |       shoppingList.value?.listItems?.forEach((item) => { | ||||||
|  |         if (!item.checked) { | ||||||
|  |           hasChanged = true; | ||||||
|  |           item.checked = true; | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |       if (hasChanged) { | ||||||
|  |         updateListItems(); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     function openUncheckAll() { | ||||||
|  |       if (shoppingList.value?.listItems?.some((item) => item.checked)) { | ||||||
|  |         state.uncheckAllDialog = true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     function uncheckAll() { |     function uncheckAll() { | ||||||
|  |       state.uncheckAllDialog = false; | ||||||
|       let hasChanged = false; |       let hasChanged = false; | ||||||
|       shoppingList.value?.listItems?.forEach((item) => { |       shoppingList.value?.listItems?.forEach((item) => { | ||||||
|         if (item.checked) { |         if (item.checked) { | ||||||
| @@ -462,6 +512,12 @@ export default defineComponent({ | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     function openDeleteChecked() { | ||||||
|  |       if (shoppingList.value?.listItems?.some((item) => item.checked)) { | ||||||
|  |         state.deleteCheckedDialog = true; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     function deleteChecked() { |     function deleteChecked() { | ||||||
|       const checked = shoppingList.value?.listItems?.filter((item) => item.checked); |       const checked = shoppingList.value?.listItems?.filter((item) => item.checked); | ||||||
|  |  | ||||||
| @@ -953,6 +1009,7 @@ export default defineComponent({ | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     return { |     return { | ||||||
|  |       ...toRefs(state), | ||||||
|       addRecipeReferenceToList, |       addRecipeReferenceToList, | ||||||
|       updateListItems, |       updateListItems, | ||||||
|       allLabels, |       allLabels, | ||||||
| @@ -963,6 +1020,7 @@ export default defineComponent({ | |||||||
|       createListItem, |       createListItem, | ||||||
|       createListItemData, |       createListItemData, | ||||||
|       deleteChecked, |       deleteChecked, | ||||||
|  |       openDeleteChecked, | ||||||
|       deleteListItem, |       deleteListItem, | ||||||
|       edit, |       edit, | ||||||
|       getLabelColor, |       getLabelColor, | ||||||
| @@ -988,6 +1046,9 @@ export default defineComponent({ | |||||||
|       sortByLabels, |       sortByLabels, | ||||||
|       toggleShowChecked, |       toggleShowChecked, | ||||||
|       uncheckAll, |       uncheckAll, | ||||||
|  |       openUncheckAll, | ||||||
|  |       checkAll, | ||||||
|  |       openCheckAll, | ||||||
|       updateIndexUnchecked, |       updateIndexUnchecked, | ||||||
|       updateIndexUncheckedByLabel, |       updateIndexUncheckedByLabel, | ||||||
|       allUnits, |       allUnits, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user