mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-04-09 14:35:35 -04:00
chore: migrate remaining pages to script setup (#7310)
This commit is contained in:
@@ -34,93 +34,87 @@
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineNuxtComponent({
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
middleware: ["can-organize-only"],
|
||||
setup() {
|
||||
const i18n = useI18n();
|
||||
const buttonLookup: { [key: string]: string } = {
|
||||
recipes: i18n.t("general.recipes"),
|
||||
recipeActions: i18n.t("recipe.recipe-actions"),
|
||||
foods: i18n.t("general.foods"),
|
||||
units: i18n.t("general.units"),
|
||||
labels: i18n.t("data-pages.labels.labels"),
|
||||
categories: i18n.t("category.categories"),
|
||||
tags: i18n.t("tag.tags"),
|
||||
tools: i18n.t("tool.tools"),
|
||||
};
|
||||
});
|
||||
|
||||
const route = useRoute();
|
||||
const i18n = useI18n();
|
||||
const buttonLookup: { [key: string]: string } = {
|
||||
recipes: i18n.t("general.recipes"),
|
||||
recipeActions: i18n.t("recipe.recipe-actions"),
|
||||
foods: i18n.t("general.foods"),
|
||||
units: i18n.t("general.units"),
|
||||
labels: i18n.t("data-pages.labels.labels"),
|
||||
categories: i18n.t("category.categories"),
|
||||
tags: i18n.t("tag.tags"),
|
||||
tools: i18n.t("tool.tools"),
|
||||
};
|
||||
|
||||
const DATA_TYPE_OPTIONS = computed(() => [
|
||||
{
|
||||
text: i18n.t("general.recipes"),
|
||||
value: "new",
|
||||
to: "/group/data/recipes",
|
||||
},
|
||||
{
|
||||
text: i18n.t("recipe.recipe-actions"),
|
||||
value: "new",
|
||||
to: "/group/data/recipe-actions",
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: i18n.t("general.foods"),
|
||||
value: "url",
|
||||
to: "/group/data/foods",
|
||||
},
|
||||
{
|
||||
text: i18n.t("general.units"),
|
||||
value: "new",
|
||||
to: "/group/data/units",
|
||||
},
|
||||
{
|
||||
text: i18n.t("data-pages.labels.labels"),
|
||||
value: "new",
|
||||
to: "/group/data/labels",
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: i18n.t("category.categories"),
|
||||
value: "new",
|
||||
to: "/group/data/categories",
|
||||
},
|
||||
{
|
||||
text: i18n.t("tag.tags"),
|
||||
value: "new",
|
||||
to: "/group/data/tags",
|
||||
},
|
||||
{
|
||||
text: i18n.t("tool.tools"),
|
||||
value: "new",
|
||||
to: "/group/data/tools",
|
||||
},
|
||||
]);
|
||||
const route = useRoute();
|
||||
|
||||
const buttonText = computed(() => {
|
||||
const last = route.path
|
||||
.split("/")
|
||||
.pop()
|
||||
// convert hypenated-values to camelCase
|
||||
?.replace(/-([a-z])/g, function (g) {
|
||||
return g[1].toUpperCase();
|
||||
});
|
||||
|
||||
if (last) {
|
||||
return buttonLookup[last];
|
||||
}
|
||||
|
||||
return i18n.t("data-pages.select-data");
|
||||
});
|
||||
|
||||
useSeoMeta({
|
||||
title: i18n.t("data-pages.data-management"),
|
||||
});
|
||||
|
||||
return {
|
||||
buttonText,
|
||||
DATA_TYPE_OPTIONS,
|
||||
};
|
||||
const DATA_TYPE_OPTIONS = computed(() => [
|
||||
{
|
||||
text: i18n.t("general.recipes"),
|
||||
value: "new",
|
||||
to: "/group/data/recipes",
|
||||
},
|
||||
{
|
||||
text: i18n.t("recipe.recipe-actions"),
|
||||
value: "new",
|
||||
to: "/group/data/recipe-actions",
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: i18n.t("general.foods"),
|
||||
value: "url",
|
||||
to: "/group/data/foods",
|
||||
},
|
||||
{
|
||||
text: i18n.t("general.units"),
|
||||
value: "new",
|
||||
to: "/group/data/units",
|
||||
},
|
||||
{
|
||||
text: i18n.t("data-pages.labels.labels"),
|
||||
value: "new",
|
||||
to: "/group/data/labels",
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: i18n.t("category.categories"),
|
||||
value: "new",
|
||||
to: "/group/data/categories",
|
||||
},
|
||||
{
|
||||
text: i18n.t("tag.tags"),
|
||||
value: "new",
|
||||
to: "/group/data/tags",
|
||||
},
|
||||
{
|
||||
text: i18n.t("tool.tools"),
|
||||
value: "new",
|
||||
to: "/group/data/tools",
|
||||
},
|
||||
]);
|
||||
|
||||
const buttonText = computed(() => {
|
||||
const last = route.path
|
||||
.split("/")
|
||||
.pop()
|
||||
// convert hypenated-values to camelCase
|
||||
?.replace(/-([a-z])/g, function (g) {
|
||||
return g[1].toUpperCase();
|
||||
});
|
||||
|
||||
if (last) {
|
||||
return buttonLookup[last];
|
||||
}
|
||||
|
||||
return i18n.t("data-pages.select-data");
|
||||
});
|
||||
|
||||
useSeoMeta({
|
||||
title: i18n.t("data-pages.data-management"),
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { useCategoryStore } from "~/composables/store";
|
||||
import { validators } from "~/composables/use-validators";
|
||||
import { fieldTypes } from "~/composables/forms";
|
||||
|
||||
@@ -2,15 +2,10 @@
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineNuxtComponent({
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
onMounted(() => {
|
||||
// Force redirect to first valid page
|
||||
router.push("/group/data/foods");
|
||||
});
|
||||
return {};
|
||||
},
|
||||
<script setup lang="ts">
|
||||
const router = useRouter();
|
||||
onMounted(() => {
|
||||
// Force redirect to first valid page
|
||||
router.push("/group/data/foods");
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -226,7 +226,7 @@
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import RecipeDataTable from "~/components/Domain/Recipe/RecipeDataTable.vue";
|
||||
import RecipeOrganizerSelector from "~/components/Domain/Recipe/RecipeOrganizerSelector.vue";
|
||||
import { useUserApi } from "~/composables/api";
|
||||
@@ -249,295 +249,266 @@ enum MODES {
|
||||
changeOwner = "changeOwner",
|
||||
}
|
||||
|
||||
export default defineNuxtComponent({
|
||||
components: { RecipeDataTable, RecipeOrganizerSelector, GroupExportData, RecipeSettingsSwitches, UserAvatar },
|
||||
definePageMeta({
|
||||
scrollToTop: true,
|
||||
setup() {
|
||||
const i18n = useI18n();
|
||||
const auth = useMealieAuth();
|
||||
const { $globals } = useNuxtApp();
|
||||
});
|
||||
|
||||
useSeoMeta({
|
||||
title: i18n.t("data-pages.recipes.recipe-data"),
|
||||
});
|
||||
const i18n = useI18n();
|
||||
const auth = useMealieAuth();
|
||||
const { $globals } = useNuxtApp();
|
||||
|
||||
const { getAllRecipes, refreshRecipes } = useRecipes(true, true, false, `householdId=${auth.user.value?.householdId || ""}`);
|
||||
const selected = ref<Recipe[]>([]);
|
||||
useSeoMeta({
|
||||
title: i18n.t("data-pages.recipes.recipe-data"),
|
||||
});
|
||||
|
||||
function resetAll() {
|
||||
selected.value = [];
|
||||
toSetTags.value = [];
|
||||
toSetCategories.value = [];
|
||||
loading.value = false;
|
||||
}
|
||||
const { refreshRecipes } = useRecipes(true, true, false, `householdId=${auth.user.value?.householdId || ""}`);
|
||||
const selected = ref<Recipe[]>([]);
|
||||
|
||||
const headers = reactive({
|
||||
id: false,
|
||||
owner: false,
|
||||
tags: true,
|
||||
tools: true,
|
||||
categories: true,
|
||||
recipeServings: false,
|
||||
recipeYieldQuantity: false,
|
||||
recipeYield: false,
|
||||
dateAdded: false,
|
||||
});
|
||||
function resetAll() {
|
||||
selected.value = [];
|
||||
toSetTags.value = [];
|
||||
toSetCategories.value = [];
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
const headerLabels = {
|
||||
id: i18n.t("general.id"),
|
||||
owner: i18n.t("general.owner"),
|
||||
tags: i18n.t("tag.tags"),
|
||||
categories: i18n.t("recipe.categories"),
|
||||
tools: i18n.t("tool.tools"),
|
||||
recipeServings: i18n.t("recipe.recipe-servings"),
|
||||
recipeYieldQuantity: i18n.t("recipe.recipe-yield"),
|
||||
recipeYield: i18n.t("recipe.recipe-yield-text"),
|
||||
dateAdded: i18n.t("general.date-added"),
|
||||
};
|
||||
const headers = reactive({
|
||||
id: false,
|
||||
owner: false,
|
||||
tags: true,
|
||||
tools: true,
|
||||
categories: true,
|
||||
recipeServings: false,
|
||||
recipeYieldQuantity: false,
|
||||
recipeYield: false,
|
||||
dateAdded: false,
|
||||
});
|
||||
|
||||
const actions: MenuItem[] = [
|
||||
{
|
||||
icon: $globals.icons.database,
|
||||
text: i18n.t("export.export"),
|
||||
event: "export-selected",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.tags,
|
||||
text: i18n.t("data-pages.recipes.tag"),
|
||||
event: "tag-selected",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.categories,
|
||||
text: i18n.t("data-pages.recipes.categorize"),
|
||||
event: "categorize-selected",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.cog,
|
||||
text: i18n.t("data-pages.recipes.update-settings"),
|
||||
event: "update-settings",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.user,
|
||||
text: i18n.t("general.change-owner"),
|
||||
event: "change-owner",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.delete,
|
||||
text: i18n.t("general.delete"),
|
||||
event: "delete-selected",
|
||||
},
|
||||
];
|
||||
const headerLabels = {
|
||||
id: i18n.t("general.id"),
|
||||
owner: i18n.t("general.owner"),
|
||||
tags: i18n.t("tag.tags"),
|
||||
categories: i18n.t("recipe.categories"),
|
||||
tools: i18n.t("tool.tools"),
|
||||
recipeServings: i18n.t("recipe.recipe-servings"),
|
||||
recipeYieldQuantity: i18n.t("recipe.recipe-yield"),
|
||||
recipeYield: i18n.t("recipe.recipe-yield-text"),
|
||||
dateAdded: i18n.t("general.date-added"),
|
||||
};
|
||||
|
||||
const api = useUserApi();
|
||||
const loading = ref(false);
|
||||
|
||||
// ===============================================================
|
||||
// Group Exports
|
||||
|
||||
const purgeExportsDialog = ref(false);
|
||||
|
||||
async function purgeExports() {
|
||||
await api.bulk.purgeExports();
|
||||
refreshExports();
|
||||
}
|
||||
|
||||
const groupExports = ref<GroupDataExport[]>([]);
|
||||
|
||||
async function refreshExports() {
|
||||
const { data } = await api.bulk.fetchExports();
|
||||
|
||||
if (data) {
|
||||
groupExports.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await refreshExports();
|
||||
});
|
||||
// ===============================================================
|
||||
// All Recipes
|
||||
|
||||
function selectAll() {
|
||||
selected.value = allRecipes.value;
|
||||
}
|
||||
|
||||
async function exportSelected() {
|
||||
loading.value = true;
|
||||
const { data } = await api.bulk.bulkExport({
|
||||
recipes: selected.value.map((x: Recipe) => x.slug ?? ""),
|
||||
exportType: "json",
|
||||
});
|
||||
|
||||
if (data) {
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
resetAll();
|
||||
refreshExports();
|
||||
}
|
||||
|
||||
const toSetTags = ref([]);
|
||||
|
||||
async function tagSelected() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
await api.bulk.bulkTag({ recipes, tags: toSetTags.value });
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
const toSetCategories = ref([]);
|
||||
|
||||
async function categorizeSelected() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
await api.bulk.bulkCategorize({ recipes, categories: toSetCategories.value });
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
async function deleteSelected() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
|
||||
await api.bulk.bulkDelete({ recipes });
|
||||
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
const recipeSettings = reactive<RecipeSettings>({
|
||||
public: false,
|
||||
showNutrition: false,
|
||||
showAssets: false,
|
||||
landscapeView: false,
|
||||
disableComments: false,
|
||||
locked: false,
|
||||
});
|
||||
|
||||
async function updateSettings() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
|
||||
await api.bulk.bulkSetSettings({ recipes, settings: recipeSettings });
|
||||
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
async function changeOwner() {
|
||||
if (!selected.value.length || !selectedOwner.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
selected.value.forEach((r) => {
|
||||
r.userId = selectedOwner.value;
|
||||
});
|
||||
|
||||
loading.value = true;
|
||||
await api.recipes.patchMany(selected.value);
|
||||
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Dialog Management
|
||||
|
||||
const dialog = reactive({
|
||||
state: false,
|
||||
title: i18n.t("data-pages.recipes.tag-recipes"),
|
||||
mode: MODES.tag,
|
||||
tag: "",
|
||||
callback: () => {
|
||||
// Stub function to be overwritten
|
||||
return Promise.resolve();
|
||||
},
|
||||
icon: $globals.icons.tags,
|
||||
});
|
||||
|
||||
function openDialog(mode: MODES) {
|
||||
const titles: Record<MODES, string> = {
|
||||
[MODES.tag]: i18n.t("data-pages.recipes.tag-recipes"),
|
||||
[MODES.category]: i18n.t("data-pages.recipes.categorize-recipes"),
|
||||
[MODES.export]: i18n.t("data-pages.recipes.export-recipes"),
|
||||
[MODES.delete]: i18n.t("data-pages.recipes.delete-recipes"),
|
||||
[MODES.updateSettings]: i18n.t("data-pages.recipes.update-settings"),
|
||||
[MODES.changeOwner]: i18n.t("general.change-owner"),
|
||||
};
|
||||
|
||||
const callbacks: Record<MODES, () => Promise<void>> = {
|
||||
[MODES.tag]: tagSelected,
|
||||
[MODES.category]: categorizeSelected,
|
||||
[MODES.export]: exportSelected,
|
||||
[MODES.delete]: deleteSelected,
|
||||
[MODES.updateSettings]: updateSettings,
|
||||
[MODES.changeOwner]: changeOwner,
|
||||
};
|
||||
|
||||
const icons: Record<MODES, string> = {
|
||||
[MODES.tag]: $globals.icons.tags,
|
||||
[MODES.category]: $globals.icons.categories,
|
||||
[MODES.export]: $globals.icons.database,
|
||||
[MODES.delete]: $globals.icons.delete,
|
||||
[MODES.updateSettings]: $globals.icons.cog,
|
||||
[MODES.changeOwner]: $globals.icons.user,
|
||||
};
|
||||
|
||||
dialog.mode = mode;
|
||||
dialog.title = titles[mode];
|
||||
dialog.callback = callbacks[mode];
|
||||
dialog.icon = icons[mode];
|
||||
dialog.state = true;
|
||||
}
|
||||
|
||||
const { store: allUsers } = useUserStore();
|
||||
const { store: households } = useHouseholdStore();
|
||||
const selectedOwner = ref("");
|
||||
const selectedOwnerHousehold = computed(() => {
|
||||
if (!selectedOwner.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const owner = allUsers.value.find(u => u.id === selectedOwner.value);
|
||||
if (!owner) {
|
||||
return null;
|
||||
};
|
||||
|
||||
return households.value.find(h => h.id === owner.householdId);
|
||||
});
|
||||
|
||||
return {
|
||||
recipeSettings,
|
||||
selectAll,
|
||||
loading,
|
||||
actions,
|
||||
allRecipes,
|
||||
categorizeSelected,
|
||||
deleteSelected,
|
||||
dialog,
|
||||
exportSelected,
|
||||
getAllRecipes,
|
||||
headerLabels,
|
||||
headers,
|
||||
MODES,
|
||||
openDialog,
|
||||
selected,
|
||||
tagSelected,
|
||||
toSetCategories,
|
||||
toSetTags,
|
||||
groupExports,
|
||||
purgeExportsDialog,
|
||||
purgeExports,
|
||||
allUsers,
|
||||
selectedOwner,
|
||||
selectedOwnerHousehold,
|
||||
};
|
||||
const actions: MenuItem[] = [
|
||||
{
|
||||
icon: $globals.icons.database,
|
||||
text: i18n.t("export.export"),
|
||||
event: "export-selected",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.tags,
|
||||
text: i18n.t("data-pages.recipes.tag"),
|
||||
event: "tag-selected",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.categories,
|
||||
text: i18n.t("data-pages.recipes.categorize"),
|
||||
event: "categorize-selected",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.cog,
|
||||
text: i18n.t("data-pages.recipes.update-settings"),
|
||||
event: "update-settings",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.user,
|
||||
text: i18n.t("general.change-owner"),
|
||||
event: "change-owner",
|
||||
},
|
||||
{
|
||||
icon: $globals.icons.delete,
|
||||
text: i18n.t("general.delete"),
|
||||
event: "delete-selected",
|
||||
},
|
||||
];
|
||||
|
||||
const api = useUserApi();
|
||||
const loading = ref(false);
|
||||
|
||||
// ===============================================================
|
||||
// Group Exports
|
||||
|
||||
const purgeExportsDialog = ref(false);
|
||||
|
||||
async function purgeExports() {
|
||||
await api.bulk.purgeExports();
|
||||
refreshExports();
|
||||
}
|
||||
|
||||
const groupExports = ref<GroupDataExport[]>([]);
|
||||
|
||||
async function refreshExports() {
|
||||
const { data } = await api.bulk.fetchExports();
|
||||
|
||||
if (data) {
|
||||
groupExports.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await refreshExports();
|
||||
});
|
||||
// ===============================================================
|
||||
// All Recipes
|
||||
|
||||
function selectAll() {
|
||||
selected.value = allRecipes.value;
|
||||
}
|
||||
|
||||
async function exportSelected() {
|
||||
loading.value = true;
|
||||
const { data } = await api.bulk.bulkExport({
|
||||
recipes: selected.value.map((x: Recipe) => x.slug ?? ""),
|
||||
exportType: "json",
|
||||
});
|
||||
|
||||
if (data) {
|
||||
console.log(data);
|
||||
}
|
||||
|
||||
resetAll();
|
||||
refreshExports();
|
||||
}
|
||||
|
||||
const toSetTags = ref([]);
|
||||
|
||||
async function tagSelected() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
await api.bulk.bulkTag({ recipes, tags: toSetTags.value });
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
const toSetCategories = ref([]);
|
||||
|
||||
async function categorizeSelected() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
await api.bulk.bulkCategorize({ recipes, categories: toSetCategories.value });
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
async function deleteSelected() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
|
||||
await api.bulk.bulkDelete({ recipes });
|
||||
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
const recipeSettings = reactive<RecipeSettings>({
|
||||
public: false,
|
||||
showNutrition: false,
|
||||
showAssets: false,
|
||||
landscapeView: false,
|
||||
disableComments: false,
|
||||
locked: false,
|
||||
});
|
||||
|
||||
async function updateSettings() {
|
||||
loading.value = true;
|
||||
|
||||
const recipes = selected.value.map((x: Recipe) => x.slug ?? "");
|
||||
|
||||
await api.bulk.bulkSetSettings({ recipes, settings: recipeSettings });
|
||||
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
async function changeOwner() {
|
||||
if (!selected.value.length || !selectedOwner.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
selected.value.forEach((r) => {
|
||||
r.userId = selectedOwner.value;
|
||||
});
|
||||
|
||||
loading.value = true;
|
||||
await api.recipes.patchMany(selected.value);
|
||||
|
||||
await refreshRecipes();
|
||||
resetAll();
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Dialog Management
|
||||
|
||||
const dialog = reactive({
|
||||
state: false,
|
||||
title: i18n.t("data-pages.recipes.tag-recipes"),
|
||||
mode: MODES.tag,
|
||||
tag: "",
|
||||
callback: () => {
|
||||
// Stub function to be overwritten
|
||||
return Promise.resolve();
|
||||
},
|
||||
icon: $globals.icons.tags,
|
||||
});
|
||||
|
||||
function openDialog(mode: MODES) {
|
||||
const titles: Record<MODES, string> = {
|
||||
[MODES.tag]: i18n.t("data-pages.recipes.tag-recipes"),
|
||||
[MODES.category]: i18n.t("data-pages.recipes.categorize-recipes"),
|
||||
[MODES.export]: i18n.t("data-pages.recipes.export-recipes"),
|
||||
[MODES.delete]: i18n.t("data-pages.recipes.delete-recipes"),
|
||||
[MODES.updateSettings]: i18n.t("data-pages.recipes.update-settings"),
|
||||
[MODES.changeOwner]: i18n.t("general.change-owner"),
|
||||
};
|
||||
|
||||
const callbacks: Record<MODES, () => Promise<void>> = {
|
||||
[MODES.tag]: tagSelected,
|
||||
[MODES.category]: categorizeSelected,
|
||||
[MODES.export]: exportSelected,
|
||||
[MODES.delete]: deleteSelected,
|
||||
[MODES.updateSettings]: updateSettings,
|
||||
[MODES.changeOwner]: changeOwner,
|
||||
};
|
||||
|
||||
const icons: Record<MODES, string> = {
|
||||
[MODES.tag]: $globals.icons.tags,
|
||||
[MODES.category]: $globals.icons.categories,
|
||||
[MODES.export]: $globals.icons.database,
|
||||
[MODES.delete]: $globals.icons.delete,
|
||||
[MODES.updateSettings]: $globals.icons.cog,
|
||||
[MODES.changeOwner]: $globals.icons.user,
|
||||
};
|
||||
|
||||
dialog.mode = mode;
|
||||
dialog.title = titles[mode];
|
||||
dialog.callback = callbacks[mode];
|
||||
dialog.icon = icons[mode];
|
||||
dialog.state = true;
|
||||
}
|
||||
|
||||
const { store: allUsers } = useUserStore();
|
||||
const { store: households } = useHouseholdStore();
|
||||
const selectedOwner = ref("");
|
||||
const selectedOwnerHousehold = computed(() => {
|
||||
if (!selectedOwner.value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const owner = allUsers.value.find(u => u.id === selectedOwner.value);
|
||||
if (!owner) {
|
||||
return null;
|
||||
};
|
||||
|
||||
return households.value.find(h => h.id === owner.householdId);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -43,24 +43,18 @@
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { useGroupSelf } from "~/composables/use-groups";
|
||||
|
||||
export default defineNuxtComponent({
|
||||
definePageMeta({
|
||||
middleware: ["can-manage-only"],
|
||||
setup() {
|
||||
const { group, actions: groupActions } = useGroupSelf();
|
||||
const i18n = useI18n();
|
||||
});
|
||||
|
||||
useSeoMeta({
|
||||
title: i18n.t("group.group"),
|
||||
});
|
||||
const { group, actions: groupActions } = useGroupSelf();
|
||||
const i18n = useI18n();
|
||||
|
||||
return {
|
||||
group,
|
||||
groupActions,
|
||||
};
|
||||
},
|
||||
useSeoMeta({
|
||||
title: i18n.t("group.group"),
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<BaseCardSectionTitle :title="$t('migration.new-migration')" />
|
||||
<v-card
|
||||
variant="outlined"
|
||||
:loading="loading"
|
||||
:loading="state.loading"
|
||||
style="border-color: lightgrey;"
|
||||
>
|
||||
<v-card-title> {{ $t('migration.choose-migration-type') }} </v-card-title>
|
||||
@@ -29,7 +29,7 @@
|
||||
>
|
||||
<div class="mb-2">
|
||||
<BaseOverflowButton
|
||||
v-model="migrationType"
|
||||
v-model="state.migrationType"
|
||||
mode="model"
|
||||
:items="items"
|
||||
/>
|
||||
@@ -37,7 +37,7 @@
|
||||
{{ content.text }}
|
||||
<v-treeview
|
||||
v-if="content.tree && Array.isArray(content.tree)"
|
||||
:key="migrationType"
|
||||
:key="state.migrationType"
|
||||
density="compact"
|
||||
:items="content.tree"
|
||||
>
|
||||
@@ -59,15 +59,15 @@
|
||||
:text-btn="false"
|
||||
@uploaded="setFileObject"
|
||||
/>
|
||||
{{ fileObject.name || $t('migration.no-file-selected') }}
|
||||
{{ state.fileObject.name || $t('migration.no-file-selected') }}
|
||||
</v-card-text>
|
||||
|
||||
<v-card-text>
|
||||
<v-checkbox v-model="addMigrationTag">
|
||||
<v-checkbox v-model="state.addMigrationTag">
|
||||
<template #label>
|
||||
<i18n-t keypath="migration.tag-all-recipes">
|
||||
<template #tag-name>
|
||||
<b class="mx-1"> {{ migrationType }} </b>
|
||||
<b class="mx-1"> {{ state.migrationType }} </b>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</template>
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
<v-card-actions class="justify-end">
|
||||
<BaseButton
|
||||
:disabled="!fileObject.name"
|
||||
:disabled="!state.fileObject.name"
|
||||
submit
|
||||
@click="startMigration"
|
||||
>
|
||||
@@ -88,14 +88,14 @@
|
||||
<v-container class="$vuetify.display.smAndDown ? 'px-0': ''">
|
||||
<BaseCardSectionTitle :title="$t('migration.previous-migrations')" />
|
||||
<ReportTable
|
||||
:items="reports"
|
||||
:items="state.reports"
|
||||
@delete="deleteReport"
|
||||
/>
|
||||
</v-container>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import type { ReportSummary } from "~/lib/api/types/reports";
|
||||
import type { MenuItem } from "~/components/global/BaseOverflowButton.vue";
|
||||
import { useUserApi } from "~/composables/api";
|
||||
@@ -127,398 +127,387 @@ const MIGRATIONS = {
|
||||
cookn: "cookn",
|
||||
};
|
||||
|
||||
export default defineNuxtComponent({
|
||||
definePageMeta({
|
||||
middleware: ["advanced-only"],
|
||||
setup() {
|
||||
const i18n = useI18n();
|
||||
const { $globals } = useNuxtApp();
|
||||
});
|
||||
|
||||
useSeoMeta({
|
||||
title: i18n.t("settings.migrations"),
|
||||
});
|
||||
const i18n = useI18n();
|
||||
const { $globals } = useNuxtApp();
|
||||
|
||||
const api = useUserApi();
|
||||
useSeoMeta({
|
||||
title: i18n.t("settings.migrations"),
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
addMigrationTag: false,
|
||||
loading: false,
|
||||
treeState: true,
|
||||
migrationType: MIGRATIONS.mealie as SupportedMigrations,
|
||||
fileObject: {} as File,
|
||||
reports: [] as ReportSummary[],
|
||||
});
|
||||
const api = useUserApi();
|
||||
|
||||
const items: MenuItem[] = [
|
||||
{
|
||||
text: i18n.t("migration.mealie-pre-v1.title"),
|
||||
value: MIGRATIONS.mealie,
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.chowdown.title"),
|
||||
value: MIGRATIONS.chowdown,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.copymethat.title"),
|
||||
value: MIGRATIONS.copymethat,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.myrecipebox.title"),
|
||||
value: MIGRATIONS.myrecipebox,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.nextcloud.title"),
|
||||
value: MIGRATIONS.nextcloud,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.paprika.title"),
|
||||
value: MIGRATIONS.paprika,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.plantoeat.title"),
|
||||
value: MIGRATIONS.plantoeat,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.recipekeeper.title"),
|
||||
value: MIGRATIONS.recipekeeper,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.tandoor.title"),
|
||||
value: MIGRATIONS.tandoor,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.cookn.title"),
|
||||
value: MIGRATIONS.cookn,
|
||||
},
|
||||
];
|
||||
const _content: Record<string, MigrationContent> = {
|
||||
[MIGRATIONS.mealie]: {
|
||||
text: i18n.t("migration.mealie-pre-v1.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "mealie.zip",
|
||||
children: [
|
||||
{
|
||||
title: "recipes",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{
|
||||
title: "recipe-name",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe-name.json", icon: $globals.icons.codeJson },
|
||||
{
|
||||
title: "images",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "original.webp", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "recipe-name-1",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe-name-1.json", icon: $globals.icons.codeJson },
|
||||
{
|
||||
title: "images",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "original.webp", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.chowdown]: {
|
||||
text: i18n.t("migration.chowdown.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "nextcloud.zip",
|
||||
children: [
|
||||
{
|
||||
title: i18n.t("migration.recipe-1"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: i18n.t("migration.recipe-2"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.copymethat]: {
|
||||
text: i18n.t("migration.copymethat.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "Copy_Me_That_20230306.zip",
|
||||
children: [
|
||||
{
|
||||
title: "images",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe_1_an5zy.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe_2_82el8.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe_3_j75qg.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
{ title: "recipes.html", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.myrecipebox]: {
|
||||
text: i18n.t("migration.myrecipebox.description-long"),
|
||||
acceptedFileType: ".csv",
|
||||
tree: false,
|
||||
},
|
||||
[MIGRATIONS.nextcloud]: {
|
||||
text: i18n.t("migration.nextcloud.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "nextcloud.zip",
|
||||
children: [
|
||||
{
|
||||
title: i18n.t("migration.recipe-1"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: i18n.t("migration.recipe-2"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.paprika]: {
|
||||
text: i18n.t("migration.paprika.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: false,
|
||||
},
|
||||
[MIGRATIONS.plantoeat]: {
|
||||
text: i18n.t("migration.plantoeat.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "plantoeat-recipes-508318_10-13-2023.zip",
|
||||
children: [
|
||||
{ title: "plantoeat-recipes-508318_10-13-2023.csv", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.recipekeeper]: {
|
||||
text: i18n.t("migration.recipekeeper.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "recipekeeperhtml.zip",
|
||||
children: [
|
||||
{ title: "recipes.html", icon: $globals.icons.codeJson },
|
||||
{
|
||||
title: "images", icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "image1.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "image2.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.tandoor]: {
|
||||
text: i18n.t("migration.tandoor.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "tandoor_default_export_full_2023-06-29.zip",
|
||||
children: [
|
||||
{
|
||||
title: "1.zip",
|
||||
icon: $globals.icons.zip,
|
||||
children: [
|
||||
{ title: "image.jpeg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "2.zip",
|
||||
icon: $globals.icons.zip,
|
||||
children: [
|
||||
{ title: "image.jpeg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "3.zip",
|
||||
icon: $globals.icons.zip,
|
||||
children: [
|
||||
{ title: "image.jpeg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.cookn]: {
|
||||
text: i18n.t("migration.cookn.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "cookn.zip",
|
||||
children: [
|
||||
{ title: "temp_brand.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_chapter_desc.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_chapter.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_cookBook_desc.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_cookBook.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_food_brand.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_food_group.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_food.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_ingredient.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_media.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_nutrient.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_recipe_desc.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_recipe.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_unit_equivalent.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_unit.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "images", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const state = reactive({
|
||||
addMigrationTag: false,
|
||||
loading: false,
|
||||
treeState: true,
|
||||
migrationType: MIGRATIONS.mealie as SupportedMigrations,
|
||||
fileObject: {} as File,
|
||||
reports: [] as ReportSummary[],
|
||||
});
|
||||
|
||||
function addIdToNode(counter: number, node: TreeNode): number {
|
||||
node.id = counter;
|
||||
counter += 1;
|
||||
if (node.children) {
|
||||
node.children.forEach((child: TreeNode) => {
|
||||
counter = addIdToNode(counter, child);
|
||||
});
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
for (const key in _content) {
|
||||
const migration = _content[key];
|
||||
if (migration.tree && Array.isArray(migration.tree)) {
|
||||
let counter = 1;
|
||||
migration.tree.forEach((node: TreeNode) => {
|
||||
counter = addIdToNode(counter, node);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(_content);
|
||||
|
||||
function setFileObject(fileObject: File) {
|
||||
state.fileObject = fileObject;
|
||||
}
|
||||
|
||||
async function startMigration() {
|
||||
state.loading = true;
|
||||
const payload = {
|
||||
addMigrationTag: state.addMigrationTag,
|
||||
migrationType: state.migrationType,
|
||||
archive: state.fileObject,
|
||||
};
|
||||
|
||||
const { data } = await api.groupMigration.startMigration(payload);
|
||||
|
||||
state.loading = false;
|
||||
|
||||
if (data) {
|
||||
state.reports.unshift(data);
|
||||
}
|
||||
}
|
||||
|
||||
async function getMigrationReports() {
|
||||
const { data } = await api.groupReports.getAll("migration");
|
||||
|
||||
if (data) {
|
||||
state.reports = data;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteReport(id: string) {
|
||||
await api.groupReports.deleteOne(id);
|
||||
getMigrationReports();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getMigrationReports();
|
||||
});
|
||||
|
||||
const content = computed(() => {
|
||||
const data = _content[state.migrationType];
|
||||
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return {
|
||||
text: "",
|
||||
acceptedFileType: ".zip",
|
||||
tree: false,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
items,
|
||||
content,
|
||||
setFileObject,
|
||||
deleteReport,
|
||||
startMigration,
|
||||
getMigrationReports,
|
||||
};
|
||||
const items: MenuItem[] = [
|
||||
{
|
||||
text: i18n.t("migration.mealie-pre-v1.title"),
|
||||
value: MIGRATIONS.mealie,
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.chowdown.title"),
|
||||
value: MIGRATIONS.chowdown,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.copymethat.title"),
|
||||
value: MIGRATIONS.copymethat,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.myrecipebox.title"),
|
||||
value: MIGRATIONS.myrecipebox,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.nextcloud.title"),
|
||||
value: MIGRATIONS.nextcloud,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.paprika.title"),
|
||||
value: MIGRATIONS.paprika,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.plantoeat.title"),
|
||||
value: MIGRATIONS.plantoeat,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.recipekeeper.title"),
|
||||
value: MIGRATIONS.recipekeeper,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.tandoor.title"),
|
||||
value: MIGRATIONS.tandoor,
|
||||
},
|
||||
{
|
||||
text: i18n.t("migration.cookn.title"),
|
||||
value: MIGRATIONS.cookn,
|
||||
},
|
||||
];
|
||||
const _content: Record<string, MigrationContent> = {
|
||||
[MIGRATIONS.mealie]: {
|
||||
text: i18n.t("migration.mealie-pre-v1.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "mealie.zip",
|
||||
children: [
|
||||
{
|
||||
title: "recipes",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{
|
||||
title: "recipe-name",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe-name.json", icon: $globals.icons.codeJson },
|
||||
{
|
||||
title: "images",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "original.webp", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "recipe-name-1",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe-name-1.json", icon: $globals.icons.codeJson },
|
||||
{
|
||||
title: "images",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "original.webp", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.chowdown]: {
|
||||
text: i18n.t("migration.chowdown.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "nextcloud.zip",
|
||||
children: [
|
||||
{
|
||||
title: i18n.t("migration.recipe-1"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: i18n.t("migration.recipe-2"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.copymethat]: {
|
||||
text: i18n.t("migration.copymethat.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "Copy_Me_That_20230306.zip",
|
||||
children: [
|
||||
{
|
||||
title: "images",
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe_1_an5zy.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe_2_82el8.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe_3_j75qg.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
{ title: "recipes.html", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.myrecipebox]: {
|
||||
text: i18n.t("migration.myrecipebox.description-long"),
|
||||
acceptedFileType: ".csv",
|
||||
tree: false,
|
||||
},
|
||||
[MIGRATIONS.nextcloud]: {
|
||||
text: i18n.t("migration.nextcloud.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "nextcloud.zip",
|
||||
children: [
|
||||
{
|
||||
title: i18n.t("migration.recipe-1"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: i18n.t("migration.recipe-2"),
|
||||
icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
{ title: "full.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "thumb.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.paprika]: {
|
||||
text: i18n.t("migration.paprika.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: false,
|
||||
},
|
||||
[MIGRATIONS.plantoeat]: {
|
||||
text: i18n.t("migration.plantoeat.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "plantoeat-recipes-508318_10-13-2023.zip",
|
||||
children: [
|
||||
{ title: "plantoeat-recipes-508318_10-13-2023.csv", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.recipekeeper]: {
|
||||
text: i18n.t("migration.recipekeeper.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "recipekeeperhtml.zip",
|
||||
children: [
|
||||
{ title: "recipes.html", icon: $globals.icons.codeJson },
|
||||
{
|
||||
title: "images", icon: $globals.icons.folderOutline,
|
||||
children: [
|
||||
{ title: "image1.jpg", icon: $globals.icons.fileImage },
|
||||
{ title: "image2.jpg", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.tandoor]: {
|
||||
text: i18n.t("migration.tandoor.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "tandoor_default_export_full_2023-06-29.zip",
|
||||
children: [
|
||||
{
|
||||
title: "1.zip",
|
||||
icon: $globals.icons.zip,
|
||||
children: [
|
||||
{ title: "image.jpeg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "2.zip",
|
||||
icon: $globals.icons.zip,
|
||||
children: [
|
||||
{ title: "image.jpeg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "3.zip",
|
||||
icon: $globals.icons.zip,
|
||||
children: [
|
||||
{ title: "image.jpeg", icon: $globals.icons.fileImage },
|
||||
{ title: "recipe.json", icon: $globals.icons.codeJson },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
[MIGRATIONS.cookn]: {
|
||||
text: i18n.t("migration.cookn.description-long"),
|
||||
acceptedFileType: ".zip",
|
||||
tree: [
|
||||
{
|
||||
icon: $globals.icons.zip,
|
||||
title: "cookn.zip",
|
||||
children: [
|
||||
{ title: "temp_brand.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_chapter_desc.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_chapter.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_cookBook_desc.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_cookBook.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_food_brand.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_food_group.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_food.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_ingredient.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_media.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_nutrient.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_recipe_desc.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_recipe.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_unit_equivalent.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "temp_unit.dsv", icon: $globals.icons.codeJson },
|
||||
{ title: "images", icon: $globals.icons.fileImage },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
function addIdToNode(counter: number, node: TreeNode): number {
|
||||
node.id = counter;
|
||||
counter += 1;
|
||||
if (node.children) {
|
||||
node.children.forEach((child: TreeNode) => {
|
||||
counter = addIdToNode(counter, child);
|
||||
});
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
for (const key in _content) {
|
||||
const migration = _content[key];
|
||||
if (migration.tree && Array.isArray(migration.tree)) {
|
||||
let counter = 1;
|
||||
migration.tree.forEach((node: TreeNode) => {
|
||||
counter = addIdToNode(counter, node);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(_content);
|
||||
|
||||
function setFileObject(fileObject: File) {
|
||||
state.fileObject = fileObject;
|
||||
}
|
||||
|
||||
async function startMigration() {
|
||||
state.loading = true;
|
||||
const payload = {
|
||||
addMigrationTag: state.addMigrationTag,
|
||||
migrationType: state.migrationType,
|
||||
archive: state.fileObject,
|
||||
};
|
||||
|
||||
const { data } = await api.groupMigration.startMigration(payload);
|
||||
|
||||
state.loading = false;
|
||||
|
||||
if (data) {
|
||||
state.reports.unshift(data);
|
||||
}
|
||||
}
|
||||
|
||||
async function getMigrationReports() {
|
||||
const { data } = await api.groupReports.getAll("migration");
|
||||
|
||||
if (data) {
|
||||
state.reports = data;
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteReport(id: string) {
|
||||
await api.groupReports.deleteOne(id);
|
||||
getMigrationReports();
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getMigrationReports();
|
||||
});
|
||||
|
||||
const content = computed(() => {
|
||||
const data = _content[state.migrationType];
|
||||
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
return {
|
||||
text: "",
|
||||
acceptedFileType: ".zip",
|
||||
tree: false,
|
||||
};
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -47,41 +47,31 @@
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
<script setup lang="ts">
|
||||
import { useUserApi } from "~/composables/api";
|
||||
import type { ReportOut } from "~/lib/api/types/reports";
|
||||
|
||||
export default defineNuxtComponent({
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const id = route.params.id as string;
|
||||
const route = useRoute();
|
||||
const id = route.params.id as string;
|
||||
|
||||
const api = useUserApi();
|
||||
const api = useUserApi();
|
||||
|
||||
const report = ref<ReportOut | null>(null);
|
||||
const report = ref<ReportOut | null>(null);
|
||||
|
||||
async function getReport() {
|
||||
const { data } = await api.groupReports.getOne(id);
|
||||
report.value = data ?? null;
|
||||
}
|
||||
async function getReport() {
|
||||
const { data } = await api.groupReports.getOne(id);
|
||||
report.value = data ?? null;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await getReport();
|
||||
});
|
||||
|
||||
const itemHeaders = [
|
||||
{ title: "Success", value: "success" },
|
||||
{ title: "Message", value: "message" },
|
||||
{ title: "Timestamp", value: "timestamp" },
|
||||
];
|
||||
|
||||
return {
|
||||
report,
|
||||
id,
|
||||
itemHeaders,
|
||||
};
|
||||
},
|
||||
onMounted(async () => {
|
||||
await getReport();
|
||||
});
|
||||
|
||||
const itemHeaders = [
|
||||
{ title: "Success", value: "success" },
|
||||
{ title: "Message", value: "message" },
|
||||
{ title: "Timestamp", value: "timestamp" },
|
||||
];
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
||||
Reference in New Issue
Block a user