Feature/infinite scroll (#719)
* feat(frontend): ✨ lazy-load all recipes page * feat(frontend): ✨ enable runtime theme through env-variables * docs(docs): 📝 update v1 changelog * bump version Co-authored-by: Hayden <hay-kot@pm.me>
This commit is contained in:
parent
568215cf70
commit
c0dd07f9e7
21 changed files with 548 additions and 281 deletions
|
@ -11,9 +11,28 @@ services:
|
|||
- 9091:3000
|
||||
environment:
|
||||
- GLOBAL_MIDDLEWARE=auth
|
||||
- SUB_PATH=/mealie/
|
||||
# - SUB_PATH=/mealie/
|
||||
- ALLOW_SIGNUP=true
|
||||
- API_URL=http://mealie-api:80
|
||||
|
||||
# =====================================
|
||||
# Light Mode Config
|
||||
- THEME_LIGHT_PRIMARY=#E58325
|
||||
- THEME_LIGHT_ACCENT=#007A99
|
||||
- THEME_LIGHT_SECONDARY=#973542
|
||||
- THEME_LIGHT_SUCCESS=#43A047
|
||||
- THEME_LIGHT_INFO=#1976D2
|
||||
- THEME_LIGHT_WARNING=#FF6D00
|
||||
- THEME_LIGHT_ERROR=#EF5350
|
||||
# =====================================
|
||||
# Light Mode Config
|
||||
- THEME_DARK_PRIMARY=#E58325
|
||||
- THEME_DARK_ACCENT=#007A99
|
||||
- THEME_DARK_SECONDARY=#973542
|
||||
- THEME_DARK_SUCCESS=#43A047
|
||||
- THEME_DARK_INFO=#1976D2
|
||||
- THEME_DARK_WARNING=#FF6D00
|
||||
- THEME_DARK_ERROR=#EF5350
|
||||
mealie:
|
||||
container_name: mealie-api
|
||||
build:
|
||||
|
|
47
docs/docs/changelog/v1.0.0.md
Normal file
47
docs/docs/changelog/v1.0.0.md
Normal file
|
@ -0,0 +1,47 @@
|
|||
# v1.0.0 A Whole New App!
|
||||
|
||||
# DRAFT
|
||||
|
||||
!!! error "Breaking Changes"
|
||||
As you may have guessed, this release comes with some breaking changes. If you are/were consuming the API you will need to validate all endpoints as nearly all of them have changed.
|
||||
|
||||
To import your data into Mealie v1 from the most recent previous release, you'll need to export and import your data using the bult in method. **Note that only your recipes will be usable in the migration**.
|
||||
|
||||
|
||||
## ✨ What's New (What isn't?!?!)
|
||||
|
||||
### 🥳 General
|
||||
- Mealie will by default only be accessible to users. Future plans are to create spaces for non-users to access a specific group.
|
||||
- Mealie has gone through a big redesign and has tried to standerize it's look a feel a bit more across the board.
|
||||
- User/Group settings are now completly seperated from the Administration page.
|
||||
- All settings and configurations pages now have some sort of self-documenting help text. Additional text or descriptions are welcome from PRs
|
||||
|
||||
### 👨👩👧👦 Users and Groups
|
||||
- Recipes are now only viewable by group members
|
||||
- All memebers of a group can generate invitation tokens for other users to join their group
|
||||
- Users now a have "Advaced" setting to enable/disable features like Webhooks and API tokens. This will also apply to future features that are deemed as advanced.
|
||||
- "Pages" have been dropped in favor of Cookbooks which are now group specific so each group can have it's own set of cookbooks
|
||||
- Default recipe settings can now be set by the group instead of environmental variables.
|
||||
|
||||
|
||||
### 🗓 Meal Plans
|
||||
- Mealplans have been completly redesigned to use a calendar approach so you'll be able to see what meals you have planned in a more traditional view
|
||||
- Drag and Drop meals between days
|
||||
- Add Recipes or Notes to a specific day
|
||||
|
||||
### 🥙 Recipes
|
||||
- Foods/Units for Ingredients are now supported (toggle inside your recipe settings)
|
||||
- Common Food and Units come pre-packaged with Mealie
|
||||
- Recipes can now scale when Food/Units are properly defined
|
||||
- Landscape and Portrait views is now available
|
||||
|
||||
### ⚠️ Other things to know...
|
||||
- Themes have been depreciated for specific users. You can still set specific themes for your site through ENV variables. This approach should yield much better results for perforance and some weirdness users have experienced.
|
||||
- If you've experienced slowness in the past, you may notice a significant improvement in the "All Recipes" and "Search" pages, or whereever large payloads of recipes are being displayed. This is due to not validating responses from the database, as such if you are consuming these API's you may get extra values that are unexpected.
|
||||
|
||||
|
||||
### 👨💻 Backend/Development Goodies
|
||||
- Codebase is siginficantly more organized both Frontend and Backend
|
||||
- We've moved to Nuxt for SSR and Typescript for better type safety and less bugs 🎉
|
||||
- Backend now using a Class based architecture to maxamize code reuse
|
||||
- Tons of performance improvements across the board
|
|
@ -112,35 +112,48 @@ services:
|
|||
POSTGRES_USER: mealie
|
||||
```
|
||||
|
||||
## Env Variables
|
||||
## mealie-api Env Variables
|
||||
|
||||
| Variables | Default | Description |
|
||||
| ----------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PUID | 911 | UserID permissions between host OS and container |
|
||||
| PGID | 911 | GroupID permissions between host OS and container |
|
||||
| DEFAULT_GROUP | Home | The default group for users |
|
||||
| DEFAULT_EMAIL | changeme@email.com | The default username for the superuser |
|
||||
| BASE_URL | http://localhost:8080 | Used for Notifications |
|
||||
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
|
||||
| POSTGRES_USER | mealie | Postgres database user |
|
||||
| POSTGRES_PASSWORD | mealie | Postgres database password |
|
||||
| POSTGRES_SERVER | postgres | Postgres database server address |
|
||||
| POSTGRES_PORT | 5432 | Postgres database port |
|
||||
| POSTGRES_DB | mealie | Postgres database name |
|
||||
| TOKEN_TIME | 2 | The time in hours that a login/auth token is valid |
|
||||
| RECIPE_PUBLIC | True | Default Recipe Settings - Make Recipe Public |
|
||||
| RECIPE_SHOW_NUTRITION | True | Default Recipe Settings - Show Recipe Nutrition |
|
||||
| RECIPE_SHOW_ASSETS | True | Default Recipe Settings - Show Recipe Assets |
|
||||
| RECIPE_LANDSCAPE_VIEW | True | Default Recipe Settings - Set Landscape View |
|
||||
| RECIPE_DISABLE_COMMENTS | False | Default Recipe Settings - Disable Comments |
|
||||
| RECIPE_DISABLE_AMOUNT | False | Default Recipe Settings - Disable Amount |
|
||||
| API_PORT | 9000 | The port exposed by backend API. **Do not change this if you're running in Docker** |
|
||||
| API_DOCS | True | Turns on/off access to the API documentation locally. |
|
||||
| TZ | UTC | Must be set to get correct date/time on the server |
|
||||
| WORKERS_PER_CORE | 1 | Set the number of workers to the number of CPU cores multiplied by this value (Value \* CPUs). More info [here][workers_per_core] |
|
||||
| MAX_WORKERS | | Set the maximum number of workers to use. Default is not set meaning unlimited. More info [here][max_workers] |
|
||||
| WEB_CONCURRENCY | 2 | Override the automatic definition of number of workers. More info [here][web_concurrency] |
|
||||
| Variables | Default | Description |
|
||||
| ----------------- | :-------------------: | --------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| PUID | 911 | UserID permissions between host OS and container |
|
||||
| PGID | 911 | GroupID permissions between host OS and container |
|
||||
| DEFAULT_GROUP | Home | The default group for users |
|
||||
| DEFAULT_EMAIL | changeme@email.com | The default username for the superuser |
|
||||
| BASE_URL | http://localhost:8080 | Used for Notifications |
|
||||
| DB_ENGINE | sqlite | Optional: 'sqlite', 'postgres' |
|
||||
| POSTGRES_USER | mealie | Postgres database user |
|
||||
| POSTGRES_PASSWORD | mealie | Postgres database password |
|
||||
| POSTGRES_SERVER | postgres | Postgres database server address |
|
||||
| POSTGRES_PORT | 5432 | Postgres database port |
|
||||
| POSTGRES_DB | mealie | Postgres database name |
|
||||
| TOKEN_TIME | 2 | The time in hours that a login/auth token is valid |
|
||||
| API_PORT | 9000 | The port exposed by backend API. **Do not change this if you're running in Docker** |
|
||||
| API_DOCS | True | Turns on/off access to the API documentation locally. |
|
||||
| TZ | UTC | Must be set to get correct date/time on the server |
|
||||
| WORKERS_PER_CORE | 1 | Set the number of workers to the number of CPU cores multiplied by this value (Value \* CPUs). More info [here][workers_per_core] |
|
||||
| MAX_WORKERS | | Set the maximum number of workers to use. Default is not set meaning unlimited. More info [here][max_workers] |
|
||||
| WEB_CONCURRENCY | 2 | Override the automatic definition of number of workers. More info [here][web_concurrency] |
|
||||
|
||||
## mealie-frontend Env Variables
|
||||
|
||||
| Variables | Default | Description |
|
||||
| --------------------- | :-----: | ---------------------------------- |
|
||||
| ALLOW_SIGNUP | true | Allows anyone to signup for Mealie |
|
||||
| THEME_LIGHT_PRIMARY | #E58325 | Light Theme Config Variable |
|
||||
| THEME_LIGHT_ACCENT | #007A99 | Light Theme Config Variable |
|
||||
| THEME_LIGHT_SECONDARY | #973542 | Light Theme Config Variable |
|
||||
| THEME_LIGHT_SUCCESS | #43A047 | Light Theme Config Variable |
|
||||
| THEME_LIGHT_INFO | #1976D2 | Light Theme Config Variable |
|
||||
| THEME_LIGHT_WARNING | #FF6D00 | Light Theme Config Variable |
|
||||
| THEME_LIGHT_ERROR | #EF5350 | Light Theme Config Variable |
|
||||
| DARK_LIGHT_PRIMARY | #E58325 | Dark Theme Config Variable |
|
||||
| DARK_LIGHT_ACCENT | #007A99 | Dark Theme Config Variable |
|
||||
| DARK_LIGHT_SECONDARY | #973542 | Dark Theme Config Variable |
|
||||
| DARK_LIGHT_SUCCESS | #43A047 | Dark Theme Config Variable |
|
||||
| DARK_LIGHT_INFO | #1976D2 | Dark Theme Config Variable |
|
||||
| DARK_LIGHT_WARNING | #FF6D00 | Dark Theme Config Variable |
|
||||
| DARK_LIGHT_ERROR | #EF5350 | Dark Theme Config Variable |
|
||||
|
||||
## Raspberry Pi 4
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -94,6 +94,7 @@ nav:
|
|||
- Style Guide: "contributors/developers-guide/style-guide.md"
|
||||
- Development Road Map: "roadmap.md"
|
||||
- Change Log:
|
||||
- v1.0.0 A Whole New App: "changelog/v1.0.0.md"
|
||||
- v0.5.2 Misc Updates: "changelog/v0.5.2.md"
|
||||
- v0.5.1 Bug Fixes: "changelog/v0.5.1.md"
|
||||
- v0.5.0 General Upgrades: "changelog/v0.5.0.md"
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
</v-app-bar>
|
||||
<div v-if="recipes" class="mt-2">
|
||||
<v-row v-if="!viewScale">
|
||||
<v-col v-for="recipe in recipes" :key="recipe.name" :sm="6" :md="6" :lg="4" :xl="3">
|
||||
<v-col v-for="(recipe, index) in recipes" :key="recipe.slug + index" :sm="6" :md="6" :lg="4" :xl="3">
|
||||
<v-lazy>
|
||||
<RecipeCard
|
||||
:name="recipe.name"
|
||||
|
@ -72,7 +72,7 @@
|
|||
</v-row>
|
||||
<v-row v-else dense>
|
||||
<v-col
|
||||
v-for="recipe in recipes.slice(0, cardLimit)"
|
||||
v-for="recipe in recipes"
|
||||
:key="recipe.name"
|
||||
cols="12"
|
||||
:sm="singleColumn ? '12' : '12'"
|
||||
|
@ -93,11 +93,6 @@
|
|||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
<div v-intersect="bumpList" class="d-flex mt-5">
|
||||
<v-fade-transition>
|
||||
<AppLoader v-if="loading" :loading="loading" />
|
||||
</v-fade-transition>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -150,7 +145,6 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
sortLoading: false,
|
||||
cardLimit: 50,
|
||||
loading: false,
|
||||
EVENTS: {
|
||||
az: "az",
|
||||
|
@ -180,21 +174,8 @@ export default {
|
|||
return this.icon || this.$globals.icons.tags;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
recipes() {
|
||||
this.bumpList();
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
bumpList() {
|
||||
const newCardLimit = Math.min(this.cardLimit + 20, this.effectiveHardLimit);
|
||||
|
||||
if (this.loading === false && newCardLimit > this.cardLimit) {
|
||||
this.setLoader();
|
||||
}
|
||||
|
||||
this.cardLimit = newCardLimit;
|
||||
},
|
||||
async setLoader() {
|
||||
this.loading = true;
|
||||
// eslint-disable-next-line promise/param-names
|
||||
|
@ -202,7 +183,7 @@ export default {
|
|||
this.loading = false;
|
||||
},
|
||||
navigateRandom() {
|
||||
const recipe = this.utils.recipe.randomRecipe(this.recipes);
|
||||
const recipe = this.recipes[Math.floor(Math.random() * this.recipes.length)];
|
||||
this.$router.push(`/recipe/${recipe.slug}`);
|
||||
},
|
||||
sortRecipes(sortType) {
|
||||
|
|
|
@ -18,7 +18,6 @@ export default defineComponent({
|
|||
},
|
||||
setup() {
|
||||
const [state, toggle] = useToggle();
|
||||
console.log(state, toggle);
|
||||
return {
|
||||
state,
|
||||
toggle,
|
||||
|
|
|
@ -57,6 +57,26 @@ export const useSorter = () => {
|
|||
};
|
||||
};
|
||||
|
||||
export const useLazyRecipes = function () {
|
||||
const api = useApiSingleton();
|
||||
|
||||
const recipes = ref<Recipe[] | null>([]);
|
||||
|
||||
async function fetchMore(start: number, limit: number) {
|
||||
const { data } = await api.recipes.getAll(start, limit);
|
||||
if (data) {
|
||||
data.forEach((recipe) => {
|
||||
recipes.value?.push(recipe);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
recipes,
|
||||
fetchMore,
|
||||
};
|
||||
};
|
||||
|
||||
export const useRecipes = (all = false, fetchRecipes = true) => {
|
||||
const api = useApiSingleton();
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
|||
css: [{ src: "~/assets/main.css" }, { src: "~/assets/style-overrides.scss" }],
|
||||
|
||||
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
|
||||
plugins: ["~/plugins/globals.ts"],
|
||||
plugins: ["~/plugins/globals.ts", "~/plugins/theme.ts"],
|
||||
|
||||
// Auto import components: https://go.nuxtjs.dev/config-components
|
||||
components: true,
|
||||
|
@ -205,6 +205,26 @@ export default {
|
|||
axios: {
|
||||
browserBaseURL: process.env.SUB_PATH || "",
|
||||
},
|
||||
themes: {
|
||||
dark: {
|
||||
primary: process.env.THEME_DARK_PRIMARY || "#E58325",
|
||||
accent: process.env.THEME_DARK_ACCENT || "#007A99",
|
||||
secondary: process.env.THEME_DARK_SECONDARY || "#973542",
|
||||
success: process.env.THEME_DARK_SUCCESS || "#43A047",
|
||||
info: process.env.THEME_DARK_INFO || "#1976d2",
|
||||
warning: process.env.THEME_DARK_WARNING || "#FF6D00",
|
||||
error: process.env.THEME_DARK_ERROR || "#EF5350",
|
||||
},
|
||||
light: {
|
||||
primary: process.env.THEME_LIGHT_PRIMARY || "#007A99",
|
||||
accent: process.env.THEME_LIGHT_ACCENT || "#007A99",
|
||||
secondary: process.env.THEME_DARK_SECONDARY || "#973542",
|
||||
success: process.env.THEME_DARK_SUCCESS || "#43A047",
|
||||
info: process.env.THEME_LIGHT_INFO || "#1976d2",
|
||||
warning: process.env.THEME_LIGHT_WARNING || "#FF6D00",
|
||||
error: process.env.THEME_LIGHT_ERROR || "#EF5350",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
privateRuntimeConfig: {},
|
||||
|
@ -249,6 +269,8 @@ export default {
|
|||
customProperties: true,
|
||||
},
|
||||
dark: false,
|
||||
// Theme Config set at runtime by /plugins/theme.ts
|
||||
// This config doesn't do anything.
|
||||
themes: {
|
||||
dark: {
|
||||
primary: "#E58325",
|
||||
|
|
|
@ -3,23 +3,49 @@
|
|||
<RecipeCardSection
|
||||
:icon="$globals.icons.primary"
|
||||
:title="$t('page.all-recipes')"
|
||||
:recipes="allRecipes"
|
||||
@sort="assignSorted"
|
||||
:recipes="recipes"
|
||||
></RecipeCardSection>
|
||||
<v-card v-intersect="infiniteScroll"></v-card>
|
||||
<v-fade-transition>
|
||||
<AppLoader v-if="loading" :loading="loading" />
|
||||
</v-fade-transition>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from "@nuxtjs/composition-api";
|
||||
import { defineComponent, onMounted, ref } from "@nuxtjs/composition-api";
|
||||
import { useThrottleFn } from "@vueuse/core";
|
||||
import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue";
|
||||
import { useRecipes, allRecipes } from "~/composables/use-recipes";
|
||||
import { useLazyRecipes } from "~/composables/use-recipes";
|
||||
|
||||
export default defineComponent({
|
||||
components: { RecipeCardSection },
|
||||
setup() {
|
||||
const { assignSorted } = useRecipes(true);
|
||||
const start = ref(1);
|
||||
const limit = ref(30);
|
||||
const increment = ref(30);
|
||||
const ready = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
return { allRecipes, assignSorted };
|
||||
const { recipes, fetchMore } = useLazyRecipes();
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchMore(start.value, limit.value);
|
||||
ready.value = true;
|
||||
});
|
||||
|
||||
const infiniteScroll = useThrottleFn(() => {
|
||||
if (!ready.value) {
|
||||
return;
|
||||
}
|
||||
loading.value = true;
|
||||
start.value = limit.value + 1;
|
||||
limit.value = limit.value + increment.value;
|
||||
fetchMore(start.value, limit.value);
|
||||
loading.value = false;
|
||||
}, 500);
|
||||
|
||||
return { recipes, infiniteScroll, loading };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -58,8 +58,7 @@
|
|||
<RecipeCardSection
|
||||
class="mt-n5"
|
||||
:title-icon="$globals.icons.magnify"
|
||||
:recipes="showRecipes"
|
||||
:hard-limit="maxResults"
|
||||
:recipes="showRecipes.slice(0, maxResults)"
|
||||
@sort="assignFuzzy"
|
||||
/>
|
||||
</v-container>
|
||||
|
|
|
@ -1,214 +1,4 @@
|
|||
import {
|
||||
mdiAccount,
|
||||
mdiSilverwareVariant,
|
||||
mdiPlus,
|
||||
mdiPlusCircle,
|
||||
mdiDelete,
|
||||
mdiContentSave,
|
||||
mdiContentSaveEdit,
|
||||
mdiSquareEditOutline,
|
||||
mdiClose,
|
||||
mdiTagMultipleOutline,
|
||||
mdiBookOutline,
|
||||
mdiAccountCog,
|
||||
mdiAccountGroup,
|
||||
mdiHome,
|
||||
mdiMagnify,
|
||||
mdiTranslate,
|
||||
mdiClockTimeFourOutline,
|
||||
mdiImport,
|
||||
mdiEmail,
|
||||
mdiLock,
|
||||
mdiEye,
|
||||
mdiDrag,
|
||||
mdiEyeOff,
|
||||
mdiCalendarMinus,
|
||||
mdiCalendar,
|
||||
mdiDiceMultiple,
|
||||
mdiAlertCircle,
|
||||
mdiDotsVertical,
|
||||
mdiPrinter,
|
||||
mdiShareVariant,
|
||||
mdiHeart,
|
||||
mdiHeartOutline,
|
||||
mdiDotsHorizontal,
|
||||
mdiCheckboxBlankOutline,
|
||||
mdiCommentTextMultipleOutline,
|
||||
mdiDownload,
|
||||
mdiFile,
|
||||
mdiFilePdfBox,
|
||||
mdiFileImage,
|
||||
mdiCodeJson,
|
||||
mdiCog,
|
||||
mdiSort,
|
||||
mdiOrderAlphabeticalAscending,
|
||||
mdiStar,
|
||||
mdiNewBox,
|
||||
mdiShuffleVariant,
|
||||
mdiAlert,
|
||||
mdiCheckboxMarkedCircle,
|
||||
mdiInformation,
|
||||
mdiBellAlert,
|
||||
mdiRefreshCircle,
|
||||
mdiMenu,
|
||||
mdiWeatherSunny,
|
||||
mdiWeatherNight,
|
||||
mdiLink,
|
||||
mdiRobot,
|
||||
mdiLinkVariant,
|
||||
mdiViewModule,
|
||||
mdiViewDashboard,
|
||||
mdiTools,
|
||||
mdiCalendarWeek,
|
||||
mdiCalendarToday,
|
||||
mdiCalendarMultiselect,
|
||||
mdiFormatListChecks,
|
||||
mdiLogout,
|
||||
mdiContentCopy,
|
||||
mdiClipboardCheck,
|
||||
mdiCloudUpload,
|
||||
mdiDatabase,
|
||||
mdiGithub,
|
||||
mdiFolderOutline,
|
||||
mdiApi,
|
||||
mdiTestTube,
|
||||
mdiDevTo,
|
||||
mdiBackupRestore,
|
||||
mdiNotificationClearAll,
|
||||
mdiFood,
|
||||
mdiWebhook,
|
||||
mdiFilter,
|
||||
mdiAccountPlusOutline,
|
||||
mdiDesktopTowerMonitor,
|
||||
mdiFormatColorFill,
|
||||
mdiFormSelect,
|
||||
mdiPageLayoutBody,
|
||||
mdiCalendarWeekBegin,
|
||||
mdiOpenInNew,
|
||||
mdiCheck,
|
||||
mdiBroom,
|
||||
mdiCartCheck,
|
||||
mdiArrowLeftBold,
|
||||
mdiMinus,
|
||||
mdiWindowClose,
|
||||
mdiFolderZipOutline,
|
||||
mdiFoodApple,
|
||||
mdiBeakerOutline,
|
||||
mdiArrowLeftBoldOutline,
|
||||
mdiArrowRightBoldOutline,
|
||||
} from "@mdi/js";
|
||||
|
||||
const icons = {
|
||||
// Primary
|
||||
primary: mdiSilverwareVariant,
|
||||
|
||||
// General
|
||||
foods: mdiFoodApple,
|
||||
units: mdiBeakerOutline,
|
||||
alert: mdiAlert,
|
||||
alertCircle: mdiAlertCircle,
|
||||
api: mdiApi,
|
||||
arrowLeftBold: mdiArrowLeftBold,
|
||||
arrowUpDown: mdiDrag,
|
||||
backupRestore: mdiBackupRestore,
|
||||
bellAlert: mdiBellAlert,
|
||||
broom: mdiBroom,
|
||||
calendar: mdiCalendar,
|
||||
calendarMinus: mdiCalendarMinus,
|
||||
calendarMultiselect: mdiCalendarMultiselect,
|
||||
calendarToday: mdiCalendarToday,
|
||||
calendarWeek: mdiCalendarWeek,
|
||||
calendarWeekBegin: mdiCalendarWeekBegin,
|
||||
cartCheck: mdiCartCheck,
|
||||
check: mdiCheck,
|
||||
checkboxBlankOutline: mdiCheckboxBlankOutline,
|
||||
checkboxMarkedCircle: mdiCheckboxMarkedCircle,
|
||||
clipboardCheck: mdiClipboardCheck,
|
||||
clockOutline: mdiClockTimeFourOutline,
|
||||
codeBraces: mdiCodeJson,
|
||||
codeJson: mdiCodeJson,
|
||||
cog: mdiCog,
|
||||
commentTextMultipleOutline: mdiCommentTextMultipleOutline,
|
||||
contentCopy: mdiContentCopy,
|
||||
database: mdiDatabase,
|
||||
desktopTowerMonitor: mdiDesktopTowerMonitor,
|
||||
devTo: mdiDevTo,
|
||||
diceMultiple: mdiDiceMultiple,
|
||||
dotsHorizontal: mdiDotsHorizontal,
|
||||
dotsVertical: mdiDotsVertical,
|
||||
download: mdiDownload,
|
||||
email: mdiEmail,
|
||||
externalLink: mdiLinkVariant,
|
||||
eye: mdiEye,
|
||||
eyeOff: mdiEyeOff,
|
||||
file: mdiFile,
|
||||
fileImage: mdiFileImage,
|
||||
filePDF: mdiFilePdfBox,
|
||||
filter: mdiFilter,
|
||||
folderOutline: mdiFolderOutline,
|
||||
food: mdiFood,
|
||||
formatColorFill: mdiFormatColorFill,
|
||||
formatListCheck: mdiFormatListChecks,
|
||||
formSelect: mdiFormSelect,
|
||||
github: mdiGithub,
|
||||
heart: mdiHeart,
|
||||
heartOutline: mdiHeartOutline,
|
||||
home: mdiHome,
|
||||
import: mdiImport,
|
||||
information: mdiInformation,
|
||||
link: mdiLink,
|
||||
lock: mdiLock,
|
||||
logout: mdiLogout,
|
||||
menu: mdiMenu,
|
||||
newBox: mdiNewBox,
|
||||
notificationClearAll: mdiNotificationClearAll,
|
||||
openInNew: mdiOpenInNew,
|
||||
orderAlphabeticalAscending: mdiOrderAlphabeticalAscending,
|
||||
pageLayoutBody: mdiPageLayoutBody,
|
||||
printer: mdiPrinter,
|
||||
refreshCircle: mdiRefreshCircle,
|
||||
robot: mdiRobot,
|
||||
search: mdiMagnify,
|
||||
shareVariant: mdiShareVariant,
|
||||
shuffleVariant: mdiShuffleVariant,
|
||||
sort: mdiSort,
|
||||
star: mdiStar,
|
||||
testTube: mdiTestTube,
|
||||
tools: mdiTools,
|
||||
translate: mdiTranslate,
|
||||
upload: mdiCloudUpload,
|
||||
viewDashboard: mdiViewDashboard,
|
||||
viewModule: mdiViewModule,
|
||||
weatherNight: mdiWeatherNight,
|
||||
weatherSunny: mdiWeatherSunny,
|
||||
webhook: mdiWebhook,
|
||||
windowClose: mdiWindowClose,
|
||||
zip: mdiFolderZipOutline,
|
||||
|
||||
// Crud
|
||||
backArrow: mdiArrowLeftBoldOutline,
|
||||
createAlt: mdiPlus,
|
||||
create: mdiPlusCircle,
|
||||
delete: mdiDelete,
|
||||
save: mdiContentSave,
|
||||
update: mdiContentSaveEdit,
|
||||
edit: mdiSquareEditOutline,
|
||||
close: mdiClose,
|
||||
minus: mdiMinus,
|
||||
|
||||
// Organization
|
||||
tags: mdiTagMultipleOutline,
|
||||
pages: mdiBookOutline,
|
||||
|
||||
// Admin
|
||||
user: mdiAccount,
|
||||
admin: mdiAccountCog,
|
||||
group: mdiAccountGroup,
|
||||
accountPlusOutline: mdiAccountPlusOutline,
|
||||
|
||||
forward: mdiArrowRightBoldOutline,
|
||||
back: mdiArrowLeftBoldOutline,
|
||||
};
|
||||
import { icons } from "~/utils/icons";
|
||||
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
export default ({}, inject: any) => {
|
||||
|
|
3
frontend/plugins/theme.ts
Normal file
3
frontend/plugins/theme.ts
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default ({ $vuetify, $config }: any) => {
|
||||
$vuetify.theme.themes = $config.themes;
|
||||
};
|
|
@ -1,3 +1,22 @@
|
|||
GLOBAL_MIDDLEWARE=null # null or 'auth'
|
||||
GLOBAL_MIDDLEWARE=null
|
||||
BASE_URL = ""
|
||||
ALLOW_SIGNUP=true
|
||||
ALLOW_SIGNUP=true
|
||||
|
||||
# =====================================
|
||||
# Light Mode Config
|
||||
THEME_LIGHT_PRIMARY=#007A99
|
||||
THEME_LIGHT_ACCENT=#007A99
|
||||
THEME_LIGHT_SECONDARY=#973542
|
||||
THEME_LIGHT_SUCCESS=#43A047
|
||||
THEME_LIGHT_INFO=#1976D2
|
||||
THEME_LIGHT_WARNING=#FF6D00
|
||||
THEME_LIGHT_ERROR=#EF5350
|
||||
# =====================================
|
||||
# Light Mode Config
|
||||
THEME_DARK_PRIMARY=#E58325
|
||||
THEME_DARK_ACCENT=#007A99
|
||||
THEME_DARK_SECONDARY=#973542
|
||||
THEME_DARK_SUCCESS=#43A047
|
||||
THEME_DARK_INFO=#1976D2
|
||||
THEME_DARK_WARNING=#FF6D00
|
||||
THEME_DARK_ERROR=#EF5350
|
9
frontend/types/vue.d.ts
vendored
9
frontend/types/vue.d.ts
vendored
|
@ -1,5 +1,10 @@
|
|||
import Vue from "vue";
|
||||
import "@nuxt/types";
|
||||
import { Icon } from "~/utils/icons/icon-type";
|
||||
|
||||
interface Globals {
|
||||
icons: Icon;
|
||||
}
|
||||
|
||||
declare module "vue/types/vue" {
|
||||
interface Vue {
|
||||
|
@ -9,9 +14,9 @@ declare module "vue/types/vue" {
|
|||
|
||||
declare module "vue/types/options" {
|
||||
interface ComponentOptions<V extends Vue> {
|
||||
$globals?: any;
|
||||
$globals?: Globals;
|
||||
}
|
||||
interface ComponentOptions<V extends UseContextReturn> {
|
||||
$globals?: any;
|
||||
$globals?: Globals;
|
||||
}
|
||||
}
|
||||
|
|
111
frontend/utils/icons/icon-type.ts
Normal file
111
frontend/utils/icons/icon-type.ts
Normal file
|
@ -0,0 +1,111 @@
|
|||
export interface Icon {
|
||||
// Primary
|
||||
primary: String;
|
||||
|
||||
// General
|
||||
foods: String;
|
||||
units: String;
|
||||
alert: String;
|
||||
alertCircle: String;
|
||||
api: String;
|
||||
arrowLeftBold: String;
|
||||
arrowUpDown: String;
|
||||
backupRestore: String;
|
||||
bellAlert: String;
|
||||
broom: String;
|
||||
calendar: String;
|
||||
calendarMinus: String;
|
||||
calendarMultiselect: String;
|
||||
calendarToday: String;
|
||||
calendarWeek: String;
|
||||
calendarWeekBegin: String;
|
||||
cartCheck: String;
|
||||
check: String;
|
||||
checkboxBlankOutline: String;
|
||||
checkboxMarkedCircle: String;
|
||||
clipboardCheck: String;
|
||||
clockOutline: String;
|
||||
codeBraces: String;
|
||||
codeJson: String;
|
||||
cog: String;
|
||||
commentTextMultipleOutline: String;
|
||||
contentCopy: String;
|
||||
database: String;
|
||||
desktopTowerMonitor: String;
|
||||
devTo: String;
|
||||
diceMultiple: String;
|
||||
dotsHorizontal: String;
|
||||
dotsVertical: String;
|
||||
download: String;
|
||||
email: String;
|
||||
externalLink: String;
|
||||
eye: String;
|
||||
eyeOff: String;
|
||||
file: String;
|
||||
fileImage: String;
|
||||
filePDF: String;
|
||||
filter: String;
|
||||
folderOutline: String;
|
||||
food: String;
|
||||
formatColorFill: String;
|
||||
formatListCheck: String;
|
||||
formSelect: String;
|
||||
github: String;
|
||||
heart: String;
|
||||
heartOutline: String;
|
||||
home: String;
|
||||
import: String;
|
||||
information: String;
|
||||
link: String;
|
||||
lock: String;
|
||||
logout: String;
|
||||
menu: String;
|
||||
newBox: String;
|
||||
notificationClearAll: String;
|
||||
openInNew: String;
|
||||
orderAlphabeticalAscending: String;
|
||||
pageLayoutBody: String;
|
||||
printer: String;
|
||||
refreshCircle: String;
|
||||
robot: String;
|
||||
search: String;
|
||||
shareVariant: String;
|
||||
shuffleVariant: String;
|
||||
sort: String;
|
||||
star: String;
|
||||
testTube: String;
|
||||
tools: String;
|
||||
translate: String;
|
||||
upload: String;
|
||||
viewDashboard: String;
|
||||
viewModule: String;
|
||||
weatherNight: String;
|
||||
weatherSunny: String;
|
||||
webhook: String;
|
||||
windowClose: String;
|
||||
zip: String;
|
||||
|
||||
// Crud
|
||||
backArrow: String;
|
||||
createAlt: String;
|
||||
create: String;
|
||||
delete: String;
|
||||
save: String;
|
||||
update: String;
|
||||
edit: String;
|
||||
close: String;
|
||||
minus: String;
|
||||
|
||||
// Organization
|
||||
tags: String;
|
||||
pages: String;
|
||||
|
||||
// Admin
|
||||
user: String;
|
||||
admin: String;
|
||||
group: String;
|
||||
accountPlusOutline: String;
|
||||
|
||||
forward: String;
|
||||
back: String;
|
||||
}
|
211
frontend/utils/icons/icons.ts
Normal file
211
frontend/utils/icons/icons.ts
Normal file
|
@ -0,0 +1,211 @@
|
|||
import {
|
||||
mdiAccount,
|
||||
mdiSilverwareVariant,
|
||||
mdiPlus,
|
||||
mdiPlusCircle,
|
||||
mdiDelete,
|
||||
mdiContentSave,
|
||||
mdiContentSaveEdit,
|
||||
mdiSquareEditOutline,
|
||||
mdiClose,
|
||||
mdiTagMultipleOutline,
|
||||
mdiBookOutline,
|
||||
mdiAccountCog,
|
||||
mdiAccountGroup,
|
||||
mdiHome,
|
||||
mdiMagnify,
|
||||
mdiTranslate,
|
||||
mdiClockTimeFourOutline,
|
||||
mdiImport,
|
||||
mdiEmail,
|
||||
mdiLock,
|
||||
mdiEye,
|
||||
mdiDrag,
|
||||
mdiEyeOff,
|
||||
mdiCalendarMinus,
|
||||
mdiCalendar,
|
||||
mdiDiceMultiple,
|
||||
mdiAlertCircle,
|
||||
mdiDotsVertical,
|
||||
mdiPrinter,
|
||||
mdiShareVariant,
|
||||
mdiHeart,
|
||||
mdiHeartOutline,
|
||||
mdiDotsHorizontal,
|
||||
mdiCheckboxBlankOutline,
|
||||
mdiCommentTextMultipleOutline,
|
||||
mdiDownload,
|
||||
mdiFile,
|
||||
mdiFilePdfBox,
|
||||
mdiFileImage,
|
||||
mdiCodeJson,
|
||||
mdiCog,
|
||||
mdiSort,
|
||||
mdiOrderAlphabeticalAscending,
|
||||
mdiStar,
|
||||
mdiNewBox,
|
||||
mdiShuffleVariant,
|
||||
mdiAlert,
|
||||
mdiCheckboxMarkedCircle,
|
||||
mdiInformation,
|
||||
mdiBellAlert,
|
||||
mdiRefreshCircle,
|
||||
mdiMenu,
|
||||
mdiWeatherSunny,
|
||||
mdiWeatherNight,
|
||||
mdiLink,
|
||||
mdiRobot,
|
||||
mdiLinkVariant,
|
||||
mdiViewModule,
|
||||
mdiViewDashboard,
|
||||
mdiTools,
|
||||
mdiCalendarWeek,
|
||||
mdiCalendarToday,
|
||||
mdiCalendarMultiselect,
|
||||
mdiFormatListChecks,
|
||||
mdiLogout,
|
||||
mdiContentCopy,
|
||||
mdiClipboardCheck,
|
||||
mdiCloudUpload,
|
||||
mdiDatabase,
|
||||
mdiGithub,
|
||||
mdiFolderOutline,
|
||||
mdiApi,
|
||||
mdiTestTube,
|
||||
mdiDevTo,
|
||||
mdiBackupRestore,
|
||||
mdiNotificationClearAll,
|
||||
mdiFood,
|
||||
mdiWebhook,
|
||||
mdiFilter,
|
||||
mdiAccountPlusOutline,
|
||||
mdiDesktopTowerMonitor,
|
||||
mdiFormatColorFill,
|
||||
mdiFormSelect,
|
||||
mdiPageLayoutBody,
|
||||
mdiCalendarWeekBegin,
|
||||
mdiOpenInNew,
|
||||
mdiCheck,
|
||||
mdiBroom,
|
||||
mdiCartCheck,
|
||||
mdiArrowLeftBold,
|
||||
mdiMinus,
|
||||
mdiWindowClose,
|
||||
mdiFolderZipOutline,
|
||||
mdiFoodApple,
|
||||
mdiBeakerOutline,
|
||||
mdiArrowLeftBoldOutline,
|
||||
mdiArrowRightBoldOutline,
|
||||
} from "@mdi/js";
|
||||
|
||||
export const icons = {
|
||||
// Primary
|
||||
primary: mdiSilverwareVariant,
|
||||
|
||||
// General
|
||||
foods: mdiFoodApple,
|
||||
units: mdiBeakerOutline,
|
||||
alert: mdiAlert,
|
||||
alertCircle: mdiAlertCircle,
|
||||
api: mdiApi,
|
||||
arrowLeftBold: mdiArrowLeftBold,
|
||||
arrowUpDown: mdiDrag,
|
||||
backupRestore: mdiBackupRestore,
|
||||
bellAlert: mdiBellAlert,
|
||||
broom: mdiBroom,
|
||||
calendar: mdiCalendar,
|
||||
calendarMinus: mdiCalendarMinus,
|
||||
calendarMultiselect: mdiCalendarMultiselect,
|
||||
calendarToday: mdiCalendarToday,
|
||||
calendarWeek: mdiCalendarWeek,
|
||||
calendarWeekBegin: mdiCalendarWeekBegin,
|
||||
cartCheck: mdiCartCheck,
|
||||
check: mdiCheck,
|
||||
checkboxBlankOutline: mdiCheckboxBlankOutline,
|
||||
checkboxMarkedCircle: mdiCheckboxMarkedCircle,
|
||||
clipboardCheck: mdiClipboardCheck,
|
||||
clockOutline: mdiClockTimeFourOutline,
|
||||
codeBraces: mdiCodeJson,
|
||||
codeJson: mdiCodeJson,
|
||||
cog: mdiCog,
|
||||
commentTextMultipleOutline: mdiCommentTextMultipleOutline,
|
||||
contentCopy: mdiContentCopy,
|
||||
database: mdiDatabase,
|
||||
desktopTowerMonitor: mdiDesktopTowerMonitor,
|
||||
devTo: mdiDevTo,
|
||||
diceMultiple: mdiDiceMultiple,
|
||||
dotsHorizontal: mdiDotsHorizontal,
|
||||
dotsVertical: mdiDotsVertical,
|
||||
download: mdiDownload,
|
||||
email: mdiEmail,
|
||||
externalLink: mdiLinkVariant,
|
||||
eye: mdiEye,
|
||||
eyeOff: mdiEyeOff,
|
||||
file: mdiFile,
|
||||
fileImage: mdiFileImage,
|
||||
filePDF: mdiFilePdfBox,
|
||||
filter: mdiFilter,
|
||||
folderOutline: mdiFolderOutline,
|
||||
food: mdiFood,
|
||||
formatColorFill: mdiFormatColorFill,
|
||||
formatListCheck: mdiFormatListChecks,
|
||||
formSelect: mdiFormSelect,
|
||||
github: mdiGithub,
|
||||
heart: mdiHeart,
|
||||
heartOutline: mdiHeartOutline,
|
||||
home: mdiHome,
|
||||
import: mdiImport,
|
||||
information: mdiInformation,
|
||||
link: mdiLink,
|
||||
lock: mdiLock,
|
||||
logout: mdiLogout,
|
||||
menu: mdiMenu,
|
||||
newBox: mdiNewBox,
|
||||
notificationClearAll: mdiNotificationClearAll,
|
||||
openInNew: mdiOpenInNew,
|
||||
orderAlphabeticalAscending: mdiOrderAlphabeticalAscending,
|
||||
pageLayoutBody: mdiPageLayoutBody,
|
||||
printer: mdiPrinter,
|
||||
refreshCircle: mdiRefreshCircle,
|
||||
robot: mdiRobot,
|
||||
search: mdiMagnify,
|
||||
shareVariant: mdiShareVariant,
|
||||
shuffleVariant: mdiShuffleVariant,
|
||||
sort: mdiSort,
|
||||
star: mdiStar,
|
||||
testTube: mdiTestTube,
|
||||
tools: mdiTools,
|
||||
translate: mdiTranslate,
|
||||
upload: mdiCloudUpload,
|
||||
viewDashboard: mdiViewDashboard,
|
||||
viewModule: mdiViewModule,
|
||||
weatherNight: mdiWeatherNight,
|
||||
weatherSunny: mdiWeatherSunny,
|
||||
webhook: mdiWebhook,
|
||||
windowClose: mdiWindowClose,
|
||||
zip: mdiFolderZipOutline,
|
||||
|
||||
// Crud
|
||||
backArrow: mdiArrowLeftBoldOutline,
|
||||
createAlt: mdiPlus,
|
||||
create: mdiPlusCircle,
|
||||
delete: mdiDelete,
|
||||
save: mdiContentSave,
|
||||
update: mdiContentSaveEdit,
|
||||
edit: mdiSquareEditOutline,
|
||||
close: mdiClose,
|
||||
minus: mdiMinus,
|
||||
|
||||
// Organization
|
||||
tags: mdiTagMultipleOutline,
|
||||
pages: mdiBookOutline,
|
||||
|
||||
// Admin
|
||||
user: mdiAccount,
|
||||
admin: mdiAccountCog,
|
||||
group: mdiAccountGroup,
|
||||
accountPlusOutline: mdiAccountPlusOutline,
|
||||
|
||||
forward: mdiArrowRightBoldOutline,
|
||||
back: mdiArrowLeftBoldOutline,
|
||||
};
|
1
frontend/utils/icons/index.ts
Normal file
1
frontend/utils/icons/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export { icons } from "./icons";
|
|
@ -7,8 +7,8 @@ from typing import Any, Optional, Union
|
|||
import dotenv
|
||||
from pydantic import BaseSettings, Field, PostgresDsn, validator
|
||||
|
||||
APP_VERSION = "v0.5.2"
|
||||
DB_VERSION = "v0.5.0"
|
||||
APP_VERSION = "v1.0.0b"
|
||||
DB_VERSION = "v1.0.0b"
|
||||
|
||||
CWD = Path(__file__).parent
|
||||
BASE_DIR = CWD.parent.parent
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[tool.poetry]
|
||||
name = "mealie"
|
||||
version = "0.5.2"
|
||||
version = "1.0.0b"
|
||||
description = "A Recipe Manager"
|
||||
authors = ["Hayden <hay-kot@pm.me>"]
|
||||
license = "MIT"
|
||||
|
|
|
@ -52,7 +52,7 @@ def test_non_default_settings(monkeypatch):
|
|||
def test_default_connection_args(monkeypatch):
|
||||
monkeypatch.setenv("DB_ENGINE", "sqlite")
|
||||
app_settings = AppSettings()
|
||||
assert re.match(r"sqlite:////.*mealie/dev/data/mealie_v0.5.0.db", app_settings.DB_URL)
|
||||
assert re.match(r"sqlite:////.*mealie/dev/data/mealie_v1.0.0b.db", app_settings.DB_URL)
|
||||
|
||||
|
||||
def test_pg_connection_args(monkeypatch):
|
||||
|
|
Loading…
Reference in a new issue