diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 37b43afaf..72cb90692 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -276,8 +276,9 @@ class UnitSerializer(UniqueFieldsMixin, serializers.ModelSerializer): class SupermarketCategorySerializer(UniqueFieldsMixin, WritableNestedModelSerializer): def create(self, validated_data): - obj, created = SupermarketCategory.objects.get_or_create(name=validated_data['name'], - space=self.context['request'].space) + validated_data['name'] = validated_data['name'].strip() + validated_data['space'] = self.context['request'].space + obj, created = SupermarketCategory.objects.get_or_create(**validated_data) return obj def update(self, instance, validated_data): @@ -285,7 +286,7 @@ class SupermarketCategorySerializer(UniqueFieldsMixin, WritableNestedModelSerial class Meta: model = SupermarketCategory - fields = ('id', 'name') + fields = ('id', 'name', 'description') class SupermarketCategoryRelationSerializer(WritableNestedModelSerializer): @@ -301,7 +302,7 @@ class SupermarketSerializer(UniqueFieldsMixin, SpacedModelSerializer): class Meta: model = Supermarket - fields = ('id', 'name', 'category_to_supermarket') + fields = ('id', 'name', 'description', 'category_to_supermarket') class RecipeSimpleSerializer(serializers.ModelSerializer): diff --git a/cookbook/static/vue/css/cookbook_view.css b/cookbook/static/vue/css/cookbook_view.css index f26d1f3e5..58635f0c4 100644 --- a/cookbook/static/vue/css/cookbook_view.css +++ b/cookbook/static/vue/css/cookbook_view.css @@ -1 +1 @@ -.flip-enter-active[data-v-8633bda0]{-webkit-animation-name:bounceUp-data-v-8633bda0;animation-name:bounceUp-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite}.bounceleft[data-v-8633bda0]{-webkit-animation-name:bounceLeft-data-v-8633bda0;animation-name:bounceLeft-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:1;-webkit-animation-iteration-count:1}.bounceright[data-v-8633bda0]{-webkit-animation-name:bounceRight-data-v-8633bda0;animation-name:bounceRight-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:1;-webkit-animation-iteration-count:1}@-webkit-keyframes bounceUp-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateY(-7px)}}@keyframes bounceUp-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateY(-7px)}}@-webkit-keyframes bounceLeft-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateX(-10px)}}@keyframes bounceLeft-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateX(-10px)}}@-webkit-keyframes bounceRight-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateX(10px)}}@keyframes bounceRight-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateX(10px)}}.slide-fade-enter-active{transition:all .6s ease}.slide-fade-enter,.slide-fade-leave-to{transform:translateX(10px);opacity:0} \ No newline at end of file +.touchable[data-v-18b1d8a0]{padding-right:2em;padding-left:2em;margin-right:-2em;margin-left:-2em}.flip-enter-active[data-v-8633bda0]{-webkit-animation-name:bounceUp-data-v-8633bda0;animation-name:bounceUp-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:infinite;-webkit-animation-iteration-count:infinite}.bounceleft[data-v-8633bda0]{-webkit-animation-name:bounceLeft-data-v-8633bda0;animation-name:bounceLeft-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:1;-webkit-animation-iteration-count:1}.bounceright[data-v-8633bda0]{-webkit-animation-name:bounceRight-data-v-8633bda0;animation-name:bounceRight-data-v-8633bda0;-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-timing-function:linear;animation-timing-function:linear;animation-iteration-count:1;-webkit-animation-iteration-count:1}@-webkit-keyframes bounceUp-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateY(-7px)}}@keyframes bounceUp-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateY(-7px)}}@-webkit-keyframes bounceLeft-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateX(-10px)}}@keyframes bounceLeft-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateX(-10px)}}@-webkit-keyframes bounceRight-data-v-8633bda0{0%,to{-webkit-transform:translateY(0)}50%{-webkit-transform:translateX(10px)}}@keyframes bounceRight-data-v-8633bda0{0%,to{transform:translateY(0)}50%{transform:translateX(10px)}}.slide-fade-enter-active{transition:all .6s ease}.slide-fade-enter,.slide-fade-leave-to{transform:translateX(10px);opacity:0} \ No newline at end of file diff --git a/cookbook/static/vue/css/model_list_view.css b/cookbook/static/vue/css/model_list_view.css index 12a8a2ef7..e571f12b9 100644 --- a/cookbook/static/vue/css/model_list_view.css +++ b/cookbook/static/vue/css/model_list_view.css @@ -1 +1 @@ -.shake[data-v-54948e30]{-webkit-animation:shake-data-v-54948e30 .82s cubic-bezier(.36,.07,.19,.97) both;animation:shake-data-v-54948e30 .82s cubic-bezier(.36,.07,.19,.97) both;transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;perspective:1000px}@-webkit-keyframes shake-data-v-54948e30{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}@keyframes shake-data-v-54948e30{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}} \ No newline at end of file +.touchable[data-v-18b1d8a0]{padding-right:2em;padding-left:2em;margin-right:-2em;margin-left:-2em}.shake[data-v-94120e12]{-webkit-animation:shake-data-v-94120e12 .82s cubic-bezier(.36,.07,.19,.97) both;animation:shake-data-v-94120e12 .82s cubic-bezier(.36,.07,.19,.97) both;transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden;perspective:1000px}@-webkit-keyframes shake-data-v-94120e12{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}}@keyframes shake-data-v-94120e12{10%,90%{transform:translate3d(-1px,0,0)}20%,80%{transform:translate3d(2px,0,0)}30%,50%,70%{transform:translate3d(-4px,0,0)}40%,60%{transform:translate3d(4px,0,0)}} \ No newline at end of file diff --git a/cookbook/static/vue/css/recipe_search_view.css b/cookbook/static/vue/css/recipe_search_view.css new file mode 100644 index 000000000..edb9ae0f3 --- /dev/null +++ b/cookbook/static/vue/css/recipe_search_view.css @@ -0,0 +1 @@ +.touchable[data-v-18b1d8a0]{padding-right:2em;padding-left:2em;margin-right:-2em;margin-left:-2em} \ No newline at end of file diff --git a/cookbook/static/vue/css/recipe_view.css b/cookbook/static/vue/css/recipe_view.css new file mode 100644 index 000000000..edb9ae0f3 --- /dev/null +++ b/cookbook/static/vue/css/recipe_view.css @@ -0,0 +1 @@ +.touchable[data-v-18b1d8a0]{padding-right:2em;padding-left:2em;margin-right:-2em;margin-left:-2em} \ No newline at end of file diff --git a/cookbook/static/vue/recipe_search_view.html b/cookbook/static/vue/recipe_search_view.html index 328da15e8..f49e5b138 100644 --- a/cookbook/static/vue/recipe_search_view.html +++ b/cookbook/static/vue/recipe_search_view.html @@ -1 +1 @@ -Vue App
\ No newline at end of file +Vue App
\ No newline at end of file diff --git a/cookbook/static/vue/recipe_view.html b/cookbook/static/vue/recipe_view.html index 6a477fdd5..f4f39da85 100644 --- a/cookbook/static/vue/recipe_view.html +++ b/cookbook/static/vue/recipe_view.html @@ -1 +1 @@ -Vue App
\ No newline at end of file +Vue App
\ No newline at end of file diff --git a/cookbook/urls.py b/cookbook/urls.py index 7ea95e995..e3f8fac5a 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -10,7 +10,7 @@ from cookbook.helper import dal from .models import (Comment, Food, InviteLink, Keyword, MealPlan, Recipe, RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList, - Storage, Sync, SyncLog, Unit, get_model_name) + Storage, Supermarket, SupermarketCategory, Sync, SyncLog, Unit, get_model_name) from .views import api, data, delete, edit, import_export, lists, new, views, telegram router = routers.DefaultRouter() @@ -176,7 +176,7 @@ for m in generic_models: ) ) -vue_models = [Food, Keyword, Unit] +vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory] for m in vue_models: py_name = get_model_name(m) url_name = py_name.replace('_', '-') diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 20bdd7a37..5aae3fd71 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -359,7 +359,7 @@ class SupermarketCategoryRelationViewSet(viewsets.ModelViewSet, StandardFilterMi pagination_class = DefaultPagination def get_queryset(self): - self.queryset = self.queryset.filter(supermarket__space=self.request.space) + self.queryset = self.queryset.filter(supermarket__space=self.request.space).order_by('order') return super().get_queryset() diff --git a/cookbook/views/lists.py b/cookbook/views/lists.py index 71ff6ed58..d67e320c1 100644 --- a/cookbook/views/lists.py +++ b/cookbook/views/lists.py @@ -146,7 +146,39 @@ def unit(request): "title": _("Units"), "config": { 'model': "UNIT", # *REQUIRED* name of the model in models.js - 'recipe_param': 'units' # *OPTIONAL* name of the listRecipes parameter if filtering on this attribute + 'recipe_param': 'units', # *OPTIONAL* name of the listRecipes parameter if filtering on this attribute } } - ) \ No newline at end of file + ) + + +@group_required('user') +def supermarket(request): + # recipe-param is the name of the parameters used when filtering recipes by this attribute + # model-name is the models.js name of the model, probably ALL-CAPS + return render( + request, + 'generic/model_template.html', + { + "title": _("Supermarkets"), + "config": { + 'model': "SUPERMARKET", # *REQUIRED* name of the model in models.js + } + } + ) + + +@group_required('user') +def supermarket_category(request): + # recipe-param is the name of the parameters used when filtering recipes by this attribute + # model-name is the models.js name of the model, probably ALL-CAPS + return render( + request, + 'generic/model_template.html', + { + "title": _("Shopping Categories"), + "config": { + 'model': "SHOPPING_CATEGORY", # *REQUIRED* name of the model in models.js + } + } + ) diff --git a/vue/package-lock.json b/vue/package-lock.json index 084fdb63c..245501c4e 100644 --- a/vue/package-lock.json +++ b/vue/package-lock.json @@ -24,6 +24,7 @@ "vue-multiselect": "^2.1.6", "vue-property-decorator": "^9.1.2", "vue-template-compiler": "^2.6.14", + "vue2-touch-events": "^3.2.2", "vuedraggable": "^2.24.3", "vuex": "^3.6.0", "workbox-webpack-plugin": "^6.1.5" @@ -14312,6 +14313,11 @@ "dev": true, "license": "MIT" }, + "node_modules/vue2-touch-events": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vue2-touch-events/-/vue2-touch-events-3.2.2.tgz", + "integrity": "sha512-rGV8jxgOQEJYkJCp7uOBe3hjvmG1arThrq1wGtJHwJTgi65+P2a+0l4CYcQO/U1ZFqTq2/TT2+oTE6H7Y+6Eog==" + }, "node_modules/vuedraggable": { "version": "2.24.3", "license": "MIT", @@ -17200,7 +17206,6 @@ "version": "4.5.13", "dev": true, "requires": { - "@babel/core": "^7.11.0", "@babel/helper-compilation-targets": "^7.9.6", "@babel/helper-module-imports": "^7.8.3", "@babel/plugin-proposal-class-properties": "^7.8.3", @@ -17213,7 +17218,6 @@ "@vue/babel-plugin-jsx": "^1.0.3", "@vue/babel-preset-jsx": "^1.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", - "core-js": "^3.6.5", "core-js-compat": "^3.6.5", "semver": "^6.1.0" } @@ -25155,6 +25159,11 @@ "version": "1.9.1", "dev": true }, + "vue2-touch-events": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/vue2-touch-events/-/vue2-touch-events-3.2.2.tgz", + "integrity": "sha512-rGV8jxgOQEJYkJCp7uOBe3hjvmG1arThrq1wGtJHwJTgi65+P2a+0l4CYcQO/U1ZFqTq2/TT2+oTE6H7Y+6Eog==" + }, "vuedraggable": { "version": "2.24.3", "requires": { diff --git a/vue/src/apps/ModelListView/ModelListView.vue b/vue/src/apps/ModelListView/ModelListView.vue index 04de39336..3f7058dfb 100644 --- a/vue/src/apps/ModelListView/ModelListView.vue +++ b/vue/src/apps/ModelListView/ModelListView.vue @@ -1,37 +1,80 @@ @@ -46,9 +89,10 @@ import 'bootstrap-vue/dist/bootstrap-vue.css' import {CardMixin, ApiMixin} from "@/utils/utils"; import {StandardToasts, ToastMixin} from "@/utils/utils"; -import GenericSplitLists from "@/components/GenericSplitLists"; +import GenericInfiniteCards from "@/components/GenericInfiniteCards"; import GenericHorizontalCard from "@/components/GenericHorizontalCard"; import GenericModalForm from "@/components/Modals/GenericModalForm"; +import ModelMenu from "@/components/ModelMenu"; Vue.use(BootstrapVue) @@ -57,7 +101,7 @@ export default { // or i'm capturing it incorrectly name: 'ModelListView', mixins: [CardMixin, ApiMixin, ToastMixin], - components: {GenericHorizontalCard, GenericSplitLists, GenericModalForm}, + components: {GenericHorizontalCard, GenericModalForm, GenericInfiniteCards, ModelMenu}, data() { return { // this.Models and this.Actions inherited from ApiMixin @@ -66,11 +110,14 @@ export default { right_counts: {'max': 9999, 'current': 0}, left_counts: {'max': 9999, 'current': 0}, this_model: undefined, + model_menu: undefined, this_action: undefined, this_recipe_param: undefined, this_item: {}, this_target: {}, - show_modal: false + show_modal: false, + show_split: false, + paginated: false, } }, mounted() { @@ -78,6 +125,13 @@ export default { let model_config = JSON.parse(document.getElementById('model_config').textContent) this.this_model = this.Models[model_config?.model] this.this_recipe_param = model_config?.recipe_param + this.paginated = this.this_model?.paginated ?? false + this.$nextTick(() => { + if (!this.paginated) { + this.getItems() + } + }) + }, methods: { // this.genericAPI inherited from ApiMixin @@ -165,13 +219,14 @@ export default { } this.clearState() }, - getItems: function (params) { - let column = params?.column ?? 'left' + getItems: function (params, col) { + let column = col || 'left' this.genericAPI(this.this_model, this.Actions.LIST, params).then((result) => { - if (result.data.results.length) { - this['items_' + column] = this['items_' + column].concat(result.data?.results) - this[column + '_counts']['max'] = result.data.count - this[column + '_counts']['current'] = this['items_' + column].length + let results = result.data?.results ?? result.data + if (results?.length) { + this['items_' + column] = this['items_' + column].concat(results) + this[column + '_counts']['max'] = result.data?.count ?? 0 + this[column + '_counts']['current'] = this['items_' + column]?.length } else { this[column + '_counts']['max'] = 0 this[column + '_counts']['current'] = 0 diff --git a/vue/src/apps/RecipeView/RecipeView.vue b/vue/src/apps/RecipeView/RecipeView.vue index 74dc0c115..fcd063b11 100644 --- a/vue/src/apps/RecipeView/RecipeView.vue +++ b/vue/src/apps/RecipeView/RecipeView.vue @@ -155,7 +155,6 @@ + + diff --git a/vue/src/components/GenericPill.vue b/vue/src/components/GenericPill.vue new file mode 100644 index 000000000..c443652aa --- /dev/null +++ b/vue/src/components/GenericPill.vue @@ -0,0 +1,44 @@ + + + diff --git a/vue/src/components/GenericSplitLists.vue b/vue/src/components/GenericSplitLists.vue deleted file mode 100644 index 3fb4fea97..000000000 --- a/vue/src/components/GenericSplitLists.vue +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - - diff --git a/vue/src/components/Ingredient.vue b/vue/src/components/Ingredient.vue index 0ee0c4711..8a81e5958 100644 --- a/vue/src/components/Ingredient.vue +++ b/vue/src/components/Ingredient.vue @@ -26,8 +26,11 @@
- + + + + {{ ingredient.note }}
@@ -72,3 +75,13 @@ export default { } } + + diff --git a/vue/src/components/ModelMenu.vue b/vue/src/components/ModelMenu.vue new file mode 100644 index 000000000..d22779d34 --- /dev/null +++ b/vue/src/components/ModelMenu.vue @@ -0,0 +1,61 @@ + + + \ No newline at end of file diff --git a/vue/src/locales/en.json b/vue/src/locales/en.json index 53250055e..133783f9e 100644 --- a/vue/src/locales/en.json +++ b/vue/src/locales/en.json @@ -14,7 +14,7 @@ "all_fields_optional": "All fields are optional and can be left empty.", "convert_internal": "Convert to internal recipe", "show_only_internal": "Show only internal recipes", - "show_split_screen": "Show split view", + "show_split_screen": "Split View", "Log_Recipe_Cooking": "Log Recipe Cooking", "External_Recipe_Image": "External Recipe Image", @@ -46,7 +46,7 @@ "Edit_Recipe": "Edit Recipe", "Move_Keyword": "Move Keyword", "Merge_Keyword": "Merge Keyword", - "Hide_Keywords": "Hide Keywords", + "Hide_Keywords": "Hide Keyword", "Hide_Recipes": "Hide Recipes", "Move_Up": "Move up", "Move_Down": "Move down", diff --git a/vue/src/utils/models.js b/vue/src/utils/models.js index f5fbbdc05..9acaee257 100644 --- a/vue/src/utils/models.js +++ b/vue/src/utils/models.js @@ -62,9 +62,13 @@ export class Models { 'name': i18n.t('Food'), // *OPTIONAL* : parameters will be built model -> model_type -> default 'apiName': 'Food', // *REQUIRED* : the name that is used in api.ts for this model 'model_type': this.TREE, // *OPTIONAL* : model specific params for api, if not present will attempt modeltype_create then default_create + 'paginated': true, + 'move': true, + 'merge': true, 'badges': { - 'linked_recipe': true + 'linked_recipe': true, }, + 'tags': [{'field': 'supermarket_category', 'label': 'name', 'color': 'info'}], // REQUIRED: unordered array of fields that can be set during create 'create': { // if not defined partialUpdate will use the same parameters, prepending 'id' @@ -113,6 +117,9 @@ export class Models { 'name': i18n.t('Keyword'), // *OPTIONAL: parameters will be built model -> model_type -> default 'apiName': 'Keyword', 'model_type': this.TREE, + 'paginated': true, + 'move': true, + 'merge': true, 'badges': { 'icon': true }, @@ -146,6 +153,7 @@ export class Models { static UNIT = { 'name': i18n.t('Unit'), 'apiName': 'Unit', + 'paginated': true, 'create': { 'params': [['name', 'description']], 'form': { @@ -165,7 +173,7 @@ export class Models { } } }, - 'move': false + 'merge': true } static SHOPPING_LIST = {} static RECIPE_BOOK = { @@ -220,6 +228,53 @@ export class Models { } }, } + static SHOPPING_CATEGORY_RELATION = { + 'name': i18n.t('Shopping_Category'), + 'apiName': 'SupermarketCategory', + 'create': { + 'params': [['category', 'supermarket', 'order']], + 'form': { + 'name': { + 'form_field': true, + 'type': 'text', + 'field': 'name', + 'label': i18n.t('Name'), + 'placeholder': '' + }, + 'description': { + 'form_field': true, + 'type': 'text', + 'field': 'description', + 'label': i18n.t('Description'), + 'placeholder': '' + } + } + }, + } + static SUPERMARKET = { + 'name': i18n.t('Supermarket'), + 'apiName': 'Supermarket', + 'tags': [{'field': 'category_to_supermarket', 'label': 'category::name', 'color': 'info'}], + 'create': { + 'params': [['name', 'description', 'category_to_supermarket']], + 'form': { + 'name': { + 'form_field': true, + 'type': 'text', + 'field': 'name', + 'label': i18n.t('Name'), + 'placeholder': '' + }, + 'description': { + 'form_field': true, + 'type': 'text', + 'field': 'description', + 'label': i18n.t('Description'), + 'placeholder': '' + }, + } + }, + } static RECIPE = { 'name': i18n.t('Recipe'), diff --git a/vue/webpack-stats.json b/vue/webpack-stats.json index 526210c05..11c1a3515 100644 --- a/vue/webpack-stats.json +++ b/vue/webpack-stats.json @@ -3,23 +3,23 @@ "assets": { "../../templates/sw.js": { "name": "../../templates/sw.js", - "path": "..\\..\\templates\\sw.js" + "path": "../../templates/sw.js" }, "css/chunk-vendors.css": { "name": "css/chunk-vendors.css", - "path": "css\\chunk-vendors.css" + "path": "css/chunk-vendors.css" }, "js/chunk-vendors.js": { "name": "js/chunk-vendors.js", - "path": "js\\chunk-vendors.js" + "path": "js/chunk-vendors.js" }, "css/cookbook_view.css": { "name": "css/cookbook_view.css", - "path": "css\\cookbook_view.css" + "path": "css/cookbook_view.css" }, "js/cookbook_view.js": { "name": "js/cookbook_view.js", - "path": "js\\cookbook_view.js" + "path": "js/cookbook_view.js" }, "css/edit_internal_recipe.css": { "name": "css/edit_internal_recipe.css", @@ -31,35 +31,43 @@ }, "js/import_response_view.js": { "name": "js/import_response_view.js", - "path": "js\\import_response_view.js" + "path": "js/import_response_view.js" }, "css/model_list_view.css": { "name": "css/model_list_view.css", - "path": "css\\model_list_view.css" + "path": "css/model_list_view.css" }, "js/model_list_view.js": { "name": "js/model_list_view.js", - "path": "js\\model_list_view.js" + "path": "js/model_list_view.js" }, "js/offline_view.js": { "name": "js/offline_view.js", - "path": "js\\offline_view.js" + "path": "js/offline_view.js" + }, + "css/recipe_search_view.css": { + "name": "css/recipe_search_view.css", + "path": "css/recipe_search_view.css" }, "js/recipe_search_view.js": { "name": "js/recipe_search_view.js", - "path": "js\\recipe_search_view.js" + "path": "js/recipe_search_view.js" + }, + "css/recipe_view.css": { + "name": "css/recipe_view.css", + "path": "css/recipe_view.css" }, "js/recipe_view.js": { "name": "js/recipe_view.js", - "path": "js\\recipe_view.js" + "path": "js/recipe_view.js" }, "js/supermarket_view.js": { "name": "js/supermarket_view.js", - "path": "js\\supermarket_view.js" + "path": "js/supermarket_view.js" }, "js/user_file_view.js": { "name": "js/user_file_view.js", - "path": "js\\user_file_view.js" + "path": "js/user_file_view.js" }, "recipe_search_view.html": { "name": "recipe_search_view.html", @@ -106,11 +114,13 @@ "recipe_search_view": [ "css/chunk-vendors.css", "js/chunk-vendors.js", + "css/recipe_search_view.css", "js/recipe_search_view.js" ], "recipe_view": [ "css/chunk-vendors.css", "js/chunk-vendors.js", + "css/recipe_view.css", "js/recipe_view.js" ], "offline_view": [