Fix more typing issues (#928)

* Fix or comment several ts-ignores

* Fix typing related to BaseOverflowButton

* Remove unused functionality of useCookbooks, fix usage bug

* Fix more typing, add some comments

* Only allow ts-ignore if it has a comment
This commit is contained in:
Philipp Fischbeck 2022-01-16 03:38:11 +01:00 committed by GitHub
parent c4540f1395
commit f794208862
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 126 additions and 249 deletions

View file

@ -42,8 +42,13 @@ module.exports = {
allowModifiers: true,
},
],
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-ignore": "allow-with-description",
},
],
// TODO Gradually activate all rules
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",

View file

@ -1,5 +1,5 @@
import { BaseCRUDAPI } from "../_base";
import { UserRead } from "./admin-users";
import { UserOut } from "~/types/api-types/user";
const prefix = "/api";
export interface Token {
@ -29,7 +29,7 @@ export interface GroupRead extends GroupCreate {
id: number;
categories: any[];
webhooks: any[];
users: UserRead[];
users: UserOut[];
preferences: Preferences;
}

View file

@ -1,39 +1,14 @@
import { BaseCRUDAPI } from "../_base";
import { UserIn, UserOut } from "~/types/api-types/user";
const prefix = "/api";
export interface UserCreate {
username: string;
fullName: string;
email: string;
admin: boolean;
group: string;
advanced: boolean;
canInvite: boolean;
canManage: boolean;
canOrganize: boolean;
password: string;
}
export interface UserToken {
name: string;
id: number;
createdAt: Date;
}
export interface UserRead extends UserToken {
id: number;
groupId: number;
favoriteRecipes: any[];
tokens: UserToken[];
}
const routes = {
adminUsers: `${prefix}/admin/users`,
adminUsersId: (tag: string) => `${prefix}/admin/users/${tag}`,
};
export class AdminUsersApi extends BaseCRUDAPI<UserRead, UserCreate> {
export class AdminUsersApi extends BaseCRUDAPI<UserOut, UserIn> {
baseRoute: string = routes.adminUsers;
itemRoute = routes.adminUsersId;
}

View file

@ -53,7 +53,6 @@ export class RecipeAPI extends BaseCRUDAPI<Recipe, CreateRecipe> {
async createAsset(recipeSlug: string, payload: CreateAsset) {
const formData = new FormData();
// @ts-ignore
formData.append("file", payload.file);
formData.append("name", payload.name);
formData.append("extension", payload.extension);
@ -65,8 +64,7 @@ export class RecipeAPI extends BaseCRUDAPI<Recipe, CreateRecipe> {
updateImage(slug: string, fileObject: File) {
const formData = new FormData();
formData.append("image", fileObject);
// @ts-ignore
formData.append("extension", fileObject.name.split(".").pop());
formData.append("extension", fileObject.name.split(".").pop() ?? "");
return this.requests.put<any>(routes.recipesRecipeSlugImage(slug), formData);
}

View file

@ -46,7 +46,7 @@ export interface CreateAsset {
name: string;
icon: string;
extension: string;
file?: File;
file: File;
}
export interface RecipeCommentCreate {

View file

@ -1,33 +1,19 @@
import { BaseCRUDAPI } from "../_base";
import { Recipe } from "~/types/api-types/recipe";
import { RecipeTool, RecipeToolCreate, RecipeToolResponse } from "~/types/api-types/recipe";
const prefix = "/api";
export interface CreateTool {
name: string;
onHand: boolean;
}
export interface Tool extends CreateTool {
id: number;
slug: string;
}
export interface RecipeToolResponse extends Tool {
recipes: Recipe[];
}
const routes = {
tools: `${prefix}/tools`,
toolsId: (id: string) => `${prefix}/tools/${id}`,
toolsSlug: (id: string) => `${prefix}/tools/slug/${id}`,
};
export class ToolsApi extends BaseCRUDAPI<Tool, CreateTool> {
export class ToolsApi extends BaseCRUDAPI<RecipeTool, RecipeToolCreate> {
baseRoute: string = routes.tools;
itemRoute = routes.toolsId;
async byslug(slug: string) {
return await this.requests.get<Tool>(routes.toolsSlug(slug));
return await this.requests.get<RecipeToolResponse>(routes.toolsSlug(slug));
}
}

View file

@ -2,15 +2,18 @@ import { BaseAPI } from "../_base";
const prefix = "/api";
interface DownloadData {
fileToken: string,
}
export class UtilsAPI extends BaseAPI {
async download(url: string) {
const { response } = await this.requests.get(url);
const { response } = await this.requests.get<DownloadData>(url);
if (!response) {
return;
}
// @ts-ignore
const token: string = response.data.fileToken;
const tokenURL = prefix + "/utils/download?token=" + token;

View file

@ -22,7 +22,7 @@
v-on="on"
></v-text-field>
</template>
<v-date-picker v-model="expirationDate" no-title @input="pickerMenu = false"></v-date-picker>
<v-date-picker v-model="expirationDate" no-title @input="datePickerMenu = false"></v-date-picker>
</v-menu>
</v-card-text>
<v-card-actions class="justify-end">
@ -178,4 +178,4 @@ export default defineComponent({
};
},
});
</script>
</script>

View file

@ -25,7 +25,7 @@
<script lang="ts">
import { computed, defineComponent, reactive, toRefs } from "@nuxtjs/composition-api";
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import { parseIngredientText } from "~/composables/recipes";
import { RecipeIngredient } from "~/types/api-types/recipe";

View file

@ -178,7 +178,7 @@
<script lang="ts">
import draggable from "vuedraggable";
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import { ref, toRefs, reactive, defineComponent, watch, onMounted } from "@nuxtjs/composition-api";
import { RecipeStep, IngredientReferences, RecipeIngredient } from "~/types/api-types/recipe";

View file

@ -32,9 +32,10 @@
</template>
<script lang="ts">
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import { defineComponent } from "@nuxtjs/composition-api";
import { RecipeNote } from "~/types/api-types/recipe";
export default defineComponent({
components: {
@ -42,7 +43,7 @@ export default defineComponent({
},
props: {
value: {
type: Array,
type: Array as () => RecipeNote[],
required: true,
},

View file

@ -68,7 +68,7 @@
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue";
import { Recipe } from "~/types/api-types/recipe";

View file

@ -47,13 +47,13 @@
<script lang="ts">
import { defineComponent, ref, computed } from "@nuxtjs/composition-api";
import { Tool } from "~/api/class-interfaces/tools";
import { RecipeTool } from "~/types/api-types/recipe";
import { useTools } from "~/composables/recipes";
export default defineComponent({
props: {
value: {
type: Array as () => Tool[],
type: Array as () => RecipeTool[],
required: true,
},
edit: {

View file

@ -42,7 +42,7 @@ export interface ButtonOption {
icon: string;
text: string;
event: string;
children: ButtonOption[];
children?: ButtonOption[];
}
export default defineComponent({

View file

@ -136,8 +136,6 @@ export default defineComponent({
watch: {
determineClose() {
this.submitted = false;
// @ts-ignore
this.dialog = false;
},
dialog(val) {
@ -155,12 +153,10 @@ export default defineComponent({
this.submitted = true;
},
open() {
// @ts-ignore
this.dialog = true;
this.logDeprecatedProp("open");
},
close() {
// @ts-ignore
this.dialog = false;
this.logDeprecatedProp("close");
},

View file

@ -60,9 +60,10 @@ const MODES = {
export interface MenuItem {
text: string;
icon: string;
icon?: string;
to?: string;
event: string;
value?: string;
event?: string;
}
export default defineComponent({
@ -78,6 +79,7 @@ export default defineComponent({
disabled: {
type: Boolean,
required: false,
default: false,
},
value: {
type: String,
@ -96,28 +98,24 @@ export default defineComponent({
},
},
setup(props, context) {
const activeObj = ref({
const activeObj = ref<MenuItem>({
text: "DEFAULT",
value: "",
icon: undefined,
event: undefined,
});
let startIndex = 0;
props.items.forEach((item, index) => {
// @ts-ignore
if (item.value === props.value) {
startIndex = index;
// @ts-ignore
activeObj.value = item;
}
});
const itemGroup = ref(startIndex);
function setValue(v: any) {
function setValue(v: MenuItem) {
context.emit(INPUT_EVENT, v.value);
activeObj.value = v;
activeObj.value = v;
}
return {

View file

@ -26,7 +26,7 @@
</template>
<script lang="ts">
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import { defineComponent, computed, ref } from "@nuxtjs/composition-api";

View file

@ -9,7 +9,7 @@
</template>
<script lang="ts">
// @ts-ignore
// @ts-ignore v-jsoneditor has no types
import VJsoneditor from "v-jsoneditor";
import { defineComponent } from "@nuxtjs/composition-api";

View file

@ -2,13 +2,12 @@ import { Ref } from "@nuxtjs/composition-api";
// import { useStaticRoutes } from "../api";
import { Recipe } from "~/types/api-types/recipe";
export const useRecipeMeta = (recipe: Ref<Recipe>) => {
export const useRecipeMeta = (recipe: Ref<Recipe | null>) => {
// const { recipeImage } = useStaticRoutes();
return () => {
const imageURL = "";
return {
title: recipe?.value?.name,
// @ts-ignore
mainImage: imageURL,
meta: [
{ hid: "og:title", property: "og:title", content: recipe?.value?.name || "Recipe" },

View file

@ -1,11 +1,10 @@
import { useAsync, ref } from "@nuxtjs/composition-api";
import { set } from "@vueuse/core";
import { useAsyncKey } from "../use-utils";
import { useUserApi } from "~/composables/api";
import { Recipe } from "~/types/api-types/recipe";
export const allRecipes = ref<Recipe[] | null>([]);
export const recentRecipes = ref<Recipe[] | null>([]);
export const allRecipes = ref<Recipe[]>([]);
export const recentRecipes = ref<Recipe[]>([]);
const rand = (n: number) => Math.floor(Math.random() * n);
@ -60,7 +59,7 @@ export const useSorter = () => {
export const useLazyRecipes = function () {
const api = useUserApi();
const recipes = ref<Recipe[] | null>([]);
const recipes = ref<Recipe[]>([]);
async function fetchMore(start: number, limit: number) {
const { data } = await api.recipes.getAll(start, limit);
@ -100,8 +99,7 @@ export const useRecipes = (all = false, fetchRecipes = true) => {
async function refreshRecipes() {
const { data } = await api.recipes.getAll(start, end);
if (data) {
// @ts-ignore
set(recipes, data);
recipes.value = data;
}
}

View file

@ -1,5 +1,4 @@
import { useAsync, ref, reactive } from "@nuxtjs/composition-api";
import { set } from "@vueuse/core";
import { toastLoading, loader } from "./use-toast";
import { AllBackups, ImportBackup } from "~/api/class-interfaces/backups";
import { useUserApi } from "~/composables/api";
@ -11,8 +10,7 @@ const backups = ref<AllBackups>({
function setBackups(newBackups: AllBackups | null) {
if (newBackups) {
// @ts-ignore
set(backups, newBackups);
backups.value = newBackups;
}
}

View file

@ -1,4 +1,4 @@
import { useAsync, ref, reactive, Ref } from "@nuxtjs/composition-api";
import { useAsync, ref, Ref } from "@nuxtjs/composition-api";
import { useAsyncKey } from "./use-utils";
import { useUserApi } from "~/composables/api";
import { CookBook } from "~/api/class-interfaces/group-cookbooks";
@ -24,16 +24,6 @@ export const useCookbook = function () {
export const useCookbooks = function () {
const api = useUserApi();
const loading = ref(false);
const deleteTargetId = ref(0);
const validForm = ref(true);
// @ts-ignore
const workingCookbookData: CookBook = reactive({
id: 0,
name: "",
position: 1,
categories: [],
});
const actions = {
getAll() {
@ -68,7 +58,6 @@ export const useCookbooks = function () {
this.refreshAll();
}
this.resetWorking();
loading.value = false;
},
async updateOne(updateData: CookBook) {
@ -110,18 +99,6 @@ export const useCookbooks = function () {
this.refreshAll();
}
},
resetWorking() {
workingCookbookData.id = 0;
workingCookbookData.name = "";
workingCookbookData.position = 0;
workingCookbookData.categories = [];
},
setWorking(item: CookBook) {
workingCookbookData.id = item.id;
workingCookbookData.name = item.name;
workingCookbookData.position = item.position;
workingCookbookData.categories = item.categories;
},
flushStore() {
cookbookStore = null;
},
@ -131,5 +108,5 @@ export const useCookbooks = function () {
cookbookStore = actions.getAll();
}
return { cookbooks: cookbookStore, workingCookbookData, deleteTargetId, actions, validForm };
return { cookbooks: cookbookStore, actions };
};

View file

@ -31,7 +31,7 @@ export const useMealplans = function (range: Ref<DateRange>) {
start: format(range.value.start, "yyyy-MM-dd"),
limit: format(range.value.end, "yyyy-MM-dd"),
};
// @ts-ignore
// @ts-ignore TODO Modify typing to allow for string start+limit for mealplans
const { data } = await api.mealplans.getAll(query.start, query.limit);
return data;
@ -46,7 +46,7 @@ export const useMealplans = function (range: Ref<DateRange>) {
start: format(range.value.start, "yyyy-MM-dd"),
limit: format(range.value.end, "yyyy-MM-dd"),
};
// @ts-ignore
// @ts-ignore TODO Modify typing to allow for string start+limit for mealplans
const { data } = await api.mealplans.getAll(query.start, query.limit);
if (data) {
@ -71,7 +71,7 @@ export const useMealplans = function (range: Ref<DateRange>) {
}
loading.value = true;
// @ts-ignore
// @ts-ignore TODO Modify mealpan types to be from auto-generated files
const { data } = await api.mealplans.updateOne(updateData.id, updateData);
if (data) {
this.refreshAll();

View file

@ -7,7 +7,7 @@ export function useRouterQuery(query: string) {
const param: WritableComputedRef<string> = computed({
get(): string {
console.log("Get Query Change");
// @ts-ignore
// @ts-ignore For some reason, this could also return an array
return router.value?.query[query] || "";
},
set(v: string): void {
@ -30,7 +30,6 @@ export function useRouteQuery<T extends string | string[]>(name: string, default
},
set(v) {
nextTick(() => {
// @ts-ignore
router.replace({ query: { ...route.value.query, [name]: v } });
});
},

View file

@ -13,11 +13,11 @@ export function detectServerBaseUrl(req?: IncomingMessage | null) {
return `${url.protocol}//${url.host}`;
} else if (req.headers.host) {
// TODO Socket.encrypted doesn't exist. What is needed here?
// @ts-ignore
// @ts-ignore See above
const protocol = req.socket.encrypted ? "https:" : "http:";
return `${protocol}//${req.headers.host}`;
} else if (req.socket.remoteAddress) {
// @ts-ignore
// @ts-ignore See above
const protocol = req.socket.encrypted ? "https:" : "http:";
return `${protocol}//${req.socket.localAddress || ""}:${req.socket.localPort || ""}`;
}
@ -60,7 +60,7 @@ export function deepCopy<T>(obj: T): T {
// Some other kind of object, deep-copy its
// properties into a new object
rv = Object.keys(obj).reduce(function (prev, key) {
// @ts-ignore
// @ts-ignore This is hard to make type-safe
prev[key] = deepCopy(obj[key]);
return prev;
}, {});

View file

@ -71,7 +71,6 @@ import { useCookbooks } from "~/composables/use-group-cookbooks";
export default defineComponent({
components: { AppHeader, AppSidebar, TheSnackbar },
// @ts-ignore
middleware: "auth",
setup() {
const { cookbooks } = useCookbooks();

View file

@ -27,11 +27,9 @@
import { defineComponent, useRoute, onMounted, ref } from "@nuxtjs/composition-api";
import GroupPreferencesEditor from "~/components/Domain/Group/GroupPreferencesEditor.vue";
import { useAdminApi } from "~/composables/api";
import { useGroups } from "~/composables/use-groups";
import { alert } from "~/composables/use-toast";
import { useUserForm } from "~/composables/use-users";
import { validators } from "~/composables/use-validators";
import { VForm } from "~/types/vuetify";
import { GroupRead } from "~/api/admin/admin-groups";
export default defineComponent({
components: {
@ -39,8 +37,6 @@ export default defineComponent({
},
layout: "admin",
setup() {
const { userForm } = useUserForm();
const { groups } = useGroups();
const route = useRoute();
const groupId = route.value.params.id;
@ -52,7 +48,7 @@ export default defineComponent({
const adminApi = useAdminApi();
const group = ref({});
const group = ref<GroupRead | null>(null);
const userError = ref(false);
@ -65,20 +61,17 @@ export default defineComponent({
}
if (data) {
// @ts-ignore
group.value = data;
}
});
async function handleSubmit() {
if (!refGroupEditForm.value?.validate()) {
if (!refGroupEditForm.value?.validate() || group.value === null) {
return;
}
// @ts-ignore
const { response, data } = await adminApi.groups.updateOne(group.value.id, group.value);
if (response?.status === 200 && data) {
// @ts-ignore
group.value = data;
}
}
@ -86,11 +79,8 @@ export default defineComponent({
return {
group,
userError,
userForm,
refGroupEditForm,
handleSubmit,
groups,
validators,
};
},
});

View file

@ -45,6 +45,7 @@ import { alert } from "~/composables/use-toast";
import { useUserForm } from "~/composables/use-users";
import { validators } from "~/composables/use-validators";
import { VForm } from "~/types/vuetify";
import { UserOut } from "~/types/api-types/user";
export default defineComponent({
layout: "admin",
@ -62,19 +63,7 @@ export default defineComponent({
const adminApi = useAdminApi();
const user = ref({
username: "",
fullName: "",
email: "",
admin: false,
group: "",
advanced: false,
canInvite: false,
canManage: false,
canOrganize: false,
id: 0,
groupId: 0,
});
const user = ref<UserOut | null>(null);
const userError = ref(false);
@ -87,19 +76,16 @@ export default defineComponent({
}
if (data) {
// @ts-ignore
user.value = data;
}
});
async function handleSubmit() {
if (!refNewUserForm.value?.validate()) return;
if (!refNewUserForm.value?.validate() || user.value === null) return;
// @ts-ignore
const { response, data } = await adminApi.users.updateOne(user.value.id, user.value);
if (response?.status === 200 && data) {
// @ts-ignore
user.value = data;
}
}

View file

@ -71,6 +71,8 @@ import { defineComponent, reactive, ref, toRefs } from "@nuxtjs/composition-api"
import { Confidence, Parser } from "~/api/class-interfaces/recipes/types";
import { useUserApi } from "~/composables/api";
type ConfidenceAttribute = "average" | "comment" | "name" | "unit" | "quantity" | "food";
export default defineComponent({
layout: "admin",
setup() {
@ -85,11 +87,12 @@ export default defineComponent({
const confidence = ref<Confidence>({});
function getColor(attribute: string) {
function getColor(attribute: ConfidenceAttribute) {
const percentage = getConfidence(attribute);
if (percentage === undefined)
return;
// @ts-ignore
const p_as_num = parseFloat(percentage?.replace("%", ""));
const p_as_num = parseFloat(percentage.replace("%", ""));
// Set color based off range
if (p_as_num > 75) {
@ -101,18 +104,16 @@ export default defineComponent({
}
}
function getConfidence(attribute: string) {
attribute = attribute.toLowerCase();
function getConfidence(attribute: ConfidenceAttribute) {
if (!confidence.value) {
return;
}
// @ts-ignore
const property: number = confidence.value[attribute];
if (property) {
const property = confidence.value[attribute];
if (property !== undefined) {
return `${(property * 100).toFixed(0)}%`;
}
return null;
return undefined;
}
const tryText = [
@ -150,18 +151,18 @@ export default defineComponent({
properties.unit.value = data.ingredient?.unit?.name || "";
properties.food.value = data.ingredient?.food?.name || "";
for (const property in properties) {
(["comment", "quantity", "unit", "food"] as ConfidenceAttribute[]).forEach(property => {
const color = getColor(property);
const confidence = getConfidence(property);
if (color) {
// @ts-ignore
// @ts-ignore See above
properties[property].color = color;
}
if (confidence) {
// @ts-ignore
// @ts-ignore See above
properties[property].confidence = confidence;
}
}
});
}
state.loading = false;
}
@ -169,7 +170,7 @@ export default defineComponent({
const properties = reactive({
quantity: {
subtitle: "Quantity",
value: "" as any,
value: "" as string | number,
color: null,
confidence: null,
},

View file

@ -86,7 +86,7 @@ import {
useAsync,
useContext,
} from "@nuxtjs/composition-api";
import { AdminAboutInfo, CheckAppConfig } from "~/api/admin/admin-about";
import { CheckAppConfig } from "~/api/admin/admin-about";
import { useAdminApi, useUserApi } from "~/composables/api";
import { validators } from "~/composables/use-validators";
import { useAsyncKey } from "~/composables/use-utils";
@ -96,6 +96,7 @@ interface SimpleCheck {
text: string;
successText: string;
errorText: string;
warning: boolean;
}
export default defineComponent({
@ -209,8 +210,7 @@ export default defineComponent({
const { $globals, i18n } = useContext();
// @ts-ignore
const rawAppInfo = ref<AdminAboutInfo>({
const rawAppInfo = ref({
version: "null",
versionLatest: "null",
});
@ -220,7 +220,8 @@ export default defineComponent({
const { data } = await adminApi.about.about();
if (data) {
rawAppInfo.value = data;
rawAppInfo.value.version = data.version;
rawAppInfo.value.versionLatest = data.versionLatest;
const prettyInfo = [
{

View file

@ -77,7 +77,7 @@
<script lang="ts">
import { defineComponent, useRoute, ref } from "@nuxtjs/composition-api";
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import { useStaticRoutes } from "~/composables/api";
import { parseIngredientText, useRecipe } from "~/composables/recipes";

View file

@ -446,7 +446,7 @@ import {
useRouter,
onMounted,
} from "@nuxtjs/composition-api";
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import draggable from "vuedraggable";
import { invoke, until } from "@vueuse/core";
@ -469,9 +469,8 @@ import RecipeIngredientEditor from "~/components/Domain/Recipe/RecipeIngredientE
import RecipePrintView from "~/components/Domain/Recipe/RecipePrintView.vue";
import RecipeTools from "~/components/Domain/Recipe/RecipeTools.vue";
import RecipeComments from "~/components/Domain/Recipe/RecipeComments.vue";
import { Recipe } from "~/types/api-types/recipe";
import { Recipe, RecipeTool } from "~/types/api-types/recipe";
import { uuid4, deepCopy } from "~/composables/use-utils";
import { Tool } from "~/api/class-interfaces/tools";
import { useRouteQuery } from "~/composables/use-router";
export default defineComponent({
@ -505,9 +504,8 @@ export default defineComponent({
console.log({ working: this.recipe, saved: this.originalRecipe });
if (this.form && !isSame) {
if (this.form && !isSame && this.recipe?.slug !== undefined) {
if (window.confirm("You have unsaved changes. Do you want to save before leaving?")) {
// @ts-ignore
await this.api.recipes.updateOne(this.recipe.slug, this.recipe);
}
}
@ -536,14 +534,11 @@ export default defineComponent({
// ===============================================================
// Check Before Leaving
const domSaveChangesDialog = ref(null);
const state = reactive({
form: false,
scale: 1,
hideImage: false,
imageKey: 1,
loadFailed: false,
skeleton: false,
jsonEditor: false,
jsonEditorOptions: {
@ -567,11 +562,11 @@ export default defineComponent({
const { recipeImage } = useStaticRoutes();
const { $vuetify } = useContext();
// ===========================================================================
// Layout Helpers
const { $vuetify } = useContext();
const enableLandscape = computed(() => {
const preferLandscape = recipe?.value?.settings?.landscapeView;
const smallScreen = !$vuetify.breakpoint.smAndUp;
@ -585,6 +580,10 @@ export default defineComponent({
return false;
});
const imageHeight = computed(() => {
return $vuetify.breakpoint.xs ? "200" : "400";
});
// ===========================================================================
// Button Click Event Handlers
@ -604,6 +603,10 @@ export default defineComponent({
}
}
function printRecipe() {
window.print();
}
async function closeEditor() {
state.form = false;
state.jsonEditor = false;
@ -687,7 +690,10 @@ export default defineComponent({
// ===============================================================
// Recipe Tools
async function updateTool(tool: Tool) {
async function updateTool(tool: RecipeTool) {
if (tool.id === undefined)
return;
const { response } = await api.tools.updateOne(tool.id, tool);
if (response?.status === 200) {
@ -735,7 +741,6 @@ export default defineComponent({
// ===============================================================
// Metadata
// @ts-ignore
const metaData = useRecipeMeta(recipe);
useMeta(metaData);
@ -743,9 +748,8 @@ export default defineComponent({
return {
createApiExtra,
apiNewKey,
originalRecipe,
domSaveChangesDialog,
enableLandscape,
imageHeight,
scaledYield,
toggleJson,
...toRefs(state),
@ -754,6 +758,7 @@ export default defineComponent({
loading,
addStep,
deleteRecipe,
printRecipe,
closeEditor,
updateTool,
updateRecipe,
@ -765,15 +770,5 @@ export default defineComponent({
};
},
head: {},
computed: {
imageHeight() {
return this.$vuetify.breakpoint.xs ? "200" : "400";
},
},
methods: {
printRecipe() {
window.print();
},
},
});
</script>

View file

@ -135,7 +135,6 @@ export default defineComponent({
if (data) {
parsedIng.value = data;
// @ts-ignore
errors.value = data.map((ing, index: number) => {
const unitError = !checkForUnit(ing.ingredient.unit);
const foodError = !checkForFood(ing.ingredient.food);

View file

@ -332,7 +332,8 @@ import RecipeCategoryTagSelector from "~/components/Domain/Recipe/RecipeCategory
import { validators } from "~/composables/use-validators";
import { Recipe } from "~/types/api-types/recipe";
import { alert } from "~/composables/use-toast";
import { VForm} from "~/types/vuetify";
import { VForm } from "~/types/vuetify";
import { MenuItem } from "~/components/global/BaseOverflowButton.vue";
export default defineComponent({
components: { VJsoneditor, RecipeCategoryTagSelector },
@ -344,7 +345,7 @@ export default defineComponent({
const { $globals } = useContext();
const tabs = [
const tabs: MenuItem[] = [
{
icon: $globals.icons.link,
text: "Import with URL",
@ -422,48 +423,36 @@ export default defineComponent({
// ===================================================
// Recipe URL Import
// @ts-ignore
const domUrlForm = ref<VForm>(null);
const domUrlForm = ref<VForm | null>(null);
async function createByUrl(url: string) {
if (!domUrlForm.value.validate() || url === "") {
if (!domUrlForm.value?.validate() || url === "") {
console.log("Invalid URL", url);
return;
}
state.loading = true;
const { response } = await api.recipes.createOneByUrl(url);
if (response?.status !== 201) {
// @ts-ignore
if (!response?.error?.response?.data?.detail?.message) {
state.error = true;
}
state.loading = false;
return;
}
handleResponse(response);
}
// ===================================================
// Recipe Create By Name
const newRecipeName = ref("");
// @ts-ignore
const domCreateByName = ref<VForm>(null);
const domCreateByName = ref<VForm | null>(null);
async function createByName(name: string) {
if (!domCreateByName.value.validate() || name === "") {
if (!domCreateByName.value?.validate() || name === "") {
return;
}
const { response } = await api.recipes.createOne({ name });
// TODO createOne claims to return a Recipe, but actually the API only returns a string
// @ts-ignore
// @ts-ignore See above
handleResponse(response, true);
}
// ===================================================
// Recipe Import From Zip File
// @ts-ignore
const newRecipeZip = ref<File>(null);
const newRecipeZip = ref<File | null>(null);
const newRecipeZipFileName = "archive";
async function createByZip() {

View file

@ -47,9 +47,7 @@ export default defineComponent({
}, 500);
function removeRecipe(slug: string) {
// @ts-ignore
for (let i = 0; i < recipes?.value?.length; i++) {
// @ts-ignore
if (recipes?.value[i].slug === slug) {
recipes?.value.splice(i, 1);
break;

View file

@ -115,7 +115,6 @@ export default defineComponent({
methods: {
assignSorted(val: Array<Recipe>) {
if (this.category) {
// @ts-ignore
this.category.recipes = val;
}
},

View file

@ -115,7 +115,6 @@ export default defineComponent({
methods: {
assignSorted(val: Array<Recipe>) {
if (this.tags) {
// @ts-ignore
this.tags.recipes = val;
}
},

View file

@ -109,7 +109,6 @@ export default defineComponent({
methods: {
assignSorted(val: Array<Recipe>) {
if (this.tools) {
// @ts-ignore
this.tools.recipes = val;
}
},

View file

@ -129,8 +129,7 @@ export default defineComponent({
state.joinGroup = true;
}
// @ts-ignore
const domRegisterForm = ref<VForm>(null);
const domRegisterForm = ref<VForm | null>(null);
const form = reactive({
group: "",

View file

@ -188,7 +188,7 @@ export default defineComponent({
const includesTags = check(
state.includeTags,
// @ts-ignore
// @ts-ignore See above
recipe.tags.map((x: Tag) => x.name),
state.tagFilter.matchAny,
state.tagFilter.exclude
@ -196,8 +196,7 @@ export default defineComponent({
const includesCats = check(
state.includeCategories,
// @ts-ignore
// @ts-ignore See above
recipe.recipeCategory.map((x) => x.name),
state.catFilter.matchAny,
state.catFilter.exclude
@ -205,7 +204,7 @@ export default defineComponent({
const includesFoods = check(
state.includeFoods,
// @ts-ignore
// @ts-ignore See above
recipe.recipeIngredient.map((x) => x?.food?.name || ""),
state.foodFilter.matchAny,
state.foodFilter.exclude

View file

@ -270,7 +270,7 @@ import {
useMeta,
useRoute,
} from "@nuxtjs/composition-api";
// @ts-ignore
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
// import { useRecipeMeta } from "~/composables/recipes";
import { useStaticRoutes, useUserApi } from "~/composables/api";
@ -316,7 +316,6 @@ export default defineComponent({
},
});
// @ts-ignore
const { recipeImage } = useStaticRoutes();
const { meta, title } = useMeta();
@ -330,28 +329,25 @@ export default defineComponent({
meta.value = [
{ hid: "og:title", property: "og:title", content: data.name ?? "" },
// @ts-ignore
{
hid: "og:desc",
property: "og:description",
content: data.description,
content: data.description ?? "",
},
{
hid: "og-image",
property: "og:image",
content: imageURL ?? "",
},
// @ts-ignore
{
hid: "twitter:title",
property: "twitter:title",
content: data.name,
content: data.name ?? "",
},
// @ts-ignore
{
hid: "twitter:desc",
property: "twitter:description",
content: data.description,
content: data.description ?? "",
},
{ hid: "t-type", name: "twitter:card", content: "summary_large_image" },
];

View file

@ -425,7 +425,7 @@ export default defineComponent({
shoppingList.value?.listItems.forEach((item) => {
if (item.labelId) {
labels.push({
// @ts-ignore
// @ts-ignore TODO
name: item.label.name,
id: item.labelId,
});
@ -439,7 +439,7 @@ export default defineComponent({
const items: { [prop: string]: ShoppingListItemCreate[] } = {};
const noLabel = {
"No Label": [],
"No Label": [] as ShoppingListItemCreate[],
};
shoppingList.value?.listItems.forEach((item) => {
@ -450,7 +450,6 @@ export default defineComponent({
items[item.label.name] = [item];
}
} else {
// @ts-ignore
noLabel["No Label"].push(item);
}
});

View file

@ -68,6 +68,7 @@
import { defineComponent, reactive, toRefs, useContext, computed, onMounted } from "@nuxtjs/composition-api";
import { SupportedMigration } from "~/api/class-interfaces/group-migrations";
import { ReportSummary } from "~/api/class-interfaces/group-reports";
import { MenuItem } from "~/components/global/BaseOverflowButton.vue";
import { useUserApi } from "~/composables/api";
const MIGRATIONS = {
@ -92,7 +93,7 @@ export default defineComponent({
reports: [] as ReportSummary[],
});
const items = [
const items: MenuItem[] = [
{
text: "Nextcloud",
value: MIGRATIONS.nextcloud,

View file

@ -162,6 +162,7 @@ import { useRecipes, allRecipes } from "~/composables/recipes";
import { Recipe } from "~/types/api-types/recipe";
import GroupExportData from "~/components/Domain/Group/GroupExportData.vue";
import { GroupDataExport } from "~/api/class-interfaces/recipe-bulk-actions";
import { MenuItem } from "~/components/global/BaseOverflowButton.vue";
const MODES = {
tag: "tag",
@ -191,7 +192,7 @@ export default defineComponent({
id: false,
owner: false,
tags: true,
tools: "Tools",
tools: true,
categories: true,
recipeYield: false,
dateAdded: false,
@ -207,29 +208,25 @@ export default defineComponent({
dateAdded: "Date Added",
};
const actions = [
const actions: MenuItem[] = [
{
icon: $globals.icons.database,
text: "Export",
value: 0,
event: "export-selected",
},
{
icon: $globals.icons.tags,
text: "Tag",
value: 1,
event: "tag-selected",
},
{
icon: $globals.icons.tags,
text: "Categorize",
value: 2,
event: "categorize-selected",
},
{
icon: $globals.icons.delete,
text: "Delete",
value: 3,
event: "delete-selected",
},
];
@ -264,7 +261,6 @@ export default defineComponent({
// All Recipes
function selectAll() {
// @ts-ignore
selected.value = allRecipes.value;
}

View file

@ -116,6 +116,7 @@ import { ref, reactive, defineComponent, computed, useContext, watch } from "@nu
import { useUserApi } from "~/composables/api";
import UserAvatar from "~/components/Domain/User/UserAvatar.vue";
import { VForm } from "~/types/vuetify";
import { UserOut } from "~/types/api-types/user";
export default defineComponent({
components: {
@ -123,7 +124,7 @@ export default defineComponent({
},
setup() {
const nuxtContext = useContext();
const user = computed(() => nuxtContext.$auth.user);
const user = computed(() => nuxtContext.$auth.user as unknown as UserOut);
watch(user, () => {
userCopy.value = { ...user.value };
@ -141,7 +142,6 @@ export default defineComponent({
});
async function updateUser() {
// @ts-ignore
const { response } = await api.users.updateOne(userCopy.value.id, userCopy.value);
if (response?.status === 200) {
nuxtContext.$auth.fetchUser();
@ -152,7 +152,6 @@ export default defineComponent({
if (!userCopy.value?.id) {
return;
}
// @ts-ignore
const { response } = await api.users.changePassword(userCopy.value.id, {
currentPassword: password.current,
newPassword: password.newOne,