mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-11-03 18:53:17 -05:00 
			
		
		
		
	
		
			
	
	
		
			153 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
		
		
			
		
	
	
			153 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| 
								 | 
							
								<template>
							 | 
						||
| 
								 | 
							
								  <div>
							 | 
						||
| 
								 | 
							
								    <v-dialog v-model="dialog" width="500">
							 | 
						||
| 
								 | 
							
								      <v-card>
							 | 
						||
| 
								 | 
							
								        <v-app-bar dense dark color="primary mb-2">
							 | 
						||
| 
								 | 
							
								          <v-icon large left class="mt-1">
							 | 
						||
| 
								 | 
							
								            {{ itemType === Organizer.Tool ? $globals.icons.potSteam : $globals.icons.tags }}
							 | 
						||
| 
								 | 
							
								          </v-icon>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          <v-toolbar-title class="headline">
							 | 
						||
| 
								 | 
							
								            {{ properties.title }}
							 | 
						||
| 
								 | 
							
								          </v-toolbar-title>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          <v-spacer></v-spacer>
							 | 
						||
| 
								 | 
							
								        </v-app-bar>
							 | 
						||
| 
								 | 
							
								        <v-card-title> </v-card-title>
							 | 
						||
| 
								 | 
							
								        <v-form @submit.prevent="select">
							 | 
						||
| 
								 | 
							
								          <v-card-text>
							 | 
						||
| 
								 | 
							
								            <v-text-field
							 | 
						||
| 
								 | 
							
								              v-model="name"
							 | 
						||
| 
								 | 
							
								              dense
							 | 
						||
| 
								 | 
							
								              :label="properties.label"
							 | 
						||
| 
								 | 
							
								              :rules="[rules.required]"
							 | 
						||
| 
								 | 
							
								              autofocus
							 | 
						||
| 
								 | 
							
								            ></v-text-field>
							 | 
						||
| 
								 | 
							
								            <v-checkbox v-if="itemType === Organizer.Tool" v-model="onHand" label="On Hand"></v-checkbox>
							 | 
						||
| 
								 | 
							
								          </v-card-text>
							 | 
						||
| 
								 | 
							
								          <v-card-actions>
							 | 
						||
| 
								 | 
							
								            <BaseButton cancel @click="dialog = false" />
							 | 
						||
| 
								 | 
							
								            <v-spacer></v-spacer>
							 | 
						||
| 
								 | 
							
								            <BaseButton type="submit" create :disabled="!name" />
							 | 
						||
| 
								 | 
							
								          </v-card-actions>
							 | 
						||
| 
								 | 
							
								        </v-form>
							 | 
						||
| 
								 | 
							
								      </v-card>
							 | 
						||
| 
								 | 
							
								    </v-dialog>
							 | 
						||
| 
								 | 
							
								  </div>
							 | 
						||
| 
								 | 
							
								</template>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<script lang="ts">
							 | 
						||
| 
								 | 
							
								import { computed, defineComponent, reactive, toRefs, watch } from "@nuxtjs/composition-api";
							 | 
						||
| 
								 | 
							
								import { useUserApi } from "~/composables/api";
							 | 
						||
| 
								 | 
							
								import { useCategoryStore, useTagStore, useToolStore } from "~/composables/store";
							 | 
						||
| 
								 | 
							
								import { RecipeOrganizer, Organizer } from "~/types/recipe/organizers";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const CREATED_ITEM_EVENT = "created-item";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default defineComponent({
							 | 
						||
| 
								 | 
							
								  props: {
							 | 
						||
| 
								 | 
							
								    value: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: false,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    color: {
							 | 
						||
| 
								 | 
							
								      type: String,
							 | 
						||
| 
								 | 
							
								      default: null,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    tagDialog: {
							 | 
						||
| 
								 | 
							
								      type: Boolean,
							 | 
						||
| 
								 | 
							
								      default: true,
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								    itemType: {
							 | 
						||
| 
								 | 
							
								      type: String as () => RecipeOrganizer,
							 | 
						||
| 
								 | 
							
								      default: "category",
							 | 
						||
| 
								 | 
							
								    },
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  setup(props, context) {
							 | 
						||
| 
								 | 
							
								    const state = reactive({
							 | 
						||
| 
								 | 
							
								      name: "",
							 | 
						||
| 
								 | 
							
								      onHand: false,
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const dialog = computed({
							 | 
						||
| 
								 | 
							
								      get() {
							 | 
						||
| 
								 | 
							
								        return props.value;
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								      set(value) {
							 | 
						||
| 
								 | 
							
								        context.emit("input", value);
							 | 
						||
| 
								 | 
							
								      },
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    watch(
							 | 
						||
| 
								 | 
							
								      () => props.value,
							 | 
						||
| 
								 | 
							
								      (val: boolean) => {
							 | 
						||
| 
								 | 
							
								        if (!val) state.name = "";
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const userApi = useUserApi();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const store = (() => {
							 | 
						||
| 
								 | 
							
								      switch (props.itemType) {
							 | 
						||
| 
								 | 
							
								        case Organizer.Tag:
							 | 
						||
| 
								 | 
							
								          return useTagStore();
							 | 
						||
| 
								 | 
							
								        case Organizer.Tool:
							 | 
						||
| 
								 | 
							
								          return useToolStore();
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								          return useCategoryStore();
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    })();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const properties = computed(() => {
							 | 
						||
| 
								 | 
							
								      switch (props.itemType) {
							 | 
						||
| 
								 | 
							
								        case Organizer.Tag:
							 | 
						||
| 
								 | 
							
								          return {
							 | 
						||
| 
								 | 
							
								            title: "Create a Tag",
							 | 
						||
| 
								 | 
							
								            label: "Tag Name",
							 | 
						||
| 
								 | 
							
								            api: userApi.tags,
							 | 
						||
| 
								 | 
							
								          };
							 | 
						||
| 
								 | 
							
								        case Organizer.Tool:
							 | 
						||
| 
								 | 
							
								          return {
							 | 
						||
| 
								 | 
							
								            title: "Create a Tool",
							 | 
						||
| 
								 | 
							
								            label: "Tool Name",
							 | 
						||
| 
								 | 
							
								            api: userApi.tools,
							 | 
						||
| 
								 | 
							
								          };
							 | 
						||
| 
								 | 
							
								        default:
							 | 
						||
| 
								 | 
							
								          return {
							 | 
						||
| 
								 | 
							
								            title: "Create a Category",
							 | 
						||
| 
								 | 
							
								            label: "Category Name",
							 | 
						||
| 
								 | 
							
								            api: userApi.categories,
							 | 
						||
| 
								 | 
							
								          };
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const rules = {
							 | 
						||
| 
								 | 
							
								      required: (val: string) => !!val || "A Name is Required",
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    async function select() {
							 | 
						||
| 
								 | 
							
								      if (store) {
							 | 
						||
| 
								 | 
							
								        // @ts-ignore - only property really required is the name
							 | 
						||
| 
								 | 
							
								        await store.actions.createOne({ name: state.name });
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      const newItem = store.items.value.find((item) => item.name === state.name);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      context.emit(CREATED_ITEM_EVENT, newItem);
							 | 
						||
| 
								 | 
							
								      dialog.value = false;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    return {
							 | 
						||
| 
								 | 
							
								      Organizer,
							 | 
						||
| 
								 | 
							
								      ...toRefs(state),
							 | 
						||
| 
								 | 
							
								      dialog,
							 | 
						||
| 
								 | 
							
								      properties,
							 | 
						||
| 
								 | 
							
								      rules,
							 | 
						||
| 
								 | 
							
								      select,
							 | 
						||
| 
								 | 
							
								    };
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								});
							 | 
						||
| 
								 | 
							
								</script>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								<style></style>
							 |