finished making FoodList completely generic
This commit is contained in:
@ -10,6 +10,8 @@
|
||||
@finish-action="finishAction"/>
|
||||
<generic-split-lists v-if="this_model"
|
||||
:list_name="this_model.name"
|
||||
:right_counts="right_counts"
|
||||
:left_counts="left_counts"
|
||||
@reset="resetList"
|
||||
@get-list="getItems"
|
||||
@item-action="startAction">
|
||||
@ -67,7 +69,9 @@ import GenericModalForm from "@/components/Modals/GenericModalForm";
|
||||
Vue.use(BootstrapVue)
|
||||
|
||||
export default {
|
||||
name: 'ModelListView', // TODO: make generic name
|
||||
// TODO ApiGenerator doesn't capture and share error information - would be nice to share error details when available
|
||||
// or i'm capturing it incorrectly
|
||||
name: 'ModelListView',
|
||||
mixins: [CardMixin, ToastMixin, ApiMixin],
|
||||
components: {GenericHorizontalCard, GenericSplitLists, GenericModalForm},
|
||||
data() {
|
||||
@ -75,18 +79,21 @@ export default {
|
||||
// this.Models and this.Actions inherited from ApiMixin
|
||||
items_left: [],
|
||||
items_right: [],
|
||||
load_more_left: true,
|
||||
load_more_right: true,
|
||||
right_counts: {'max': 9999, 'current': 0},
|
||||
left_counts: {'max': 9999, 'current': 0},
|
||||
this_model: undefined,
|
||||
this_action: undefined,
|
||||
this_recipe_param: undefined,
|
||||
this_item: {},
|
||||
this_target: {},
|
||||
show_modal: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let path = (window.location.pathname).split('/')
|
||||
this.this_model = this.Models[path[path.length - 2].toUpperCase()]
|
||||
// value is passed from lists.py
|
||||
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
|
||||
},
|
||||
methods: {
|
||||
// this.genericAPI inherited from ApiMixin
|
||||
@ -176,28 +183,17 @@ export default {
|
||||
}
|
||||
this.clearState()
|
||||
},
|
||||
getItems: function (params, callback) {
|
||||
getItems: function (params) {
|
||||
let column = params?.column ?? 'left'
|
||||
// TODO: does this need to be a callback?
|
||||
this.genericAPI(this.this_model, this.Actions.LIST, params).then((result) => {
|
||||
if (result.data.results.length) {
|
||||
if (column === 'left') {
|
||||
// if paginated results are in result.data.results otherwise just result.data
|
||||
this.items_left = this.items_left.concat(result.data?.results ?? result.data)
|
||||
} else if (column === 'right') {
|
||||
this.items_right = this.items_right.concat(result.data?.results ?? result.data)
|
||||
}
|
||||
// are the total elements less than the length of the array? if so, stop loading
|
||||
// TODO: generalize this to handle results in result.data
|
||||
callback(result.data.count > (column === "left" ? this.items_left.length : this.items_right.length))
|
||||
this['items_' + column] = this['items_' + column].concat(result.data?.results)
|
||||
this[column + '_counts']['current'] = this['items_' + column].length
|
||||
this[column + '_counts']['max'] = result.data.count
|
||||
|
||||
} else {
|
||||
callback(false) // stop loading
|
||||
console.log('no data returned')
|
||||
}
|
||||
// return true if total objects are still less than the length of the list
|
||||
// TODO this needs generalized to handle non-paginated data
|
||||
callback(result.data.count < (column === "left" ? this.items_left.length : this.items_right.length))
|
||||
|
||||
}).catch((err) => {
|
||||
console.log(err)
|
||||
StandardToasts.makeStandardToast(StandardToasts.FAIL_FETCH)
|
||||
@ -253,8 +249,6 @@ export default {
|
||||
// TODO make standard toast
|
||||
this.makeToast(this.$t('Success'), 'Succesfully moved resource', 'success')
|
||||
}).catch((err) => {
|
||||
// TODO none of the error checking works because the openapi generated functions don't throw an error?
|
||||
// or i'm capturing it incorrectly
|
||||
console.log(err)
|
||||
this.makeToast(this.$t('Error'), err.bodyText, 'danger')
|
||||
})
|
||||
@ -293,7 +287,7 @@ export default {
|
||||
'pageSize': 200
|
||||
}
|
||||
this.genericAPI(this.this_model, this.Actions.LIST, options).then((result) => {
|
||||
parent = this.findCard(item.id, col === 'left' ? this.items_left : this.items_right)
|
||||
parent = this.findCard(item.id, this['items_' + col])
|
||||
if (parent) {
|
||||
Vue.set(parent, 'children', result.data.results)
|
||||
Vue.set(parent, 'show_children', true)
|
||||
@ -304,15 +298,14 @@ export default {
|
||||
this.makeToast(this.$t('Error'), err.bodyText, 'danger')
|
||||
})
|
||||
},
|
||||
getRecipes: function (col, food) {
|
||||
getRecipes: function (col, item) {
|
||||
let parent = {}
|
||||
// TODO: make this generic
|
||||
let options = {
|
||||
'foods': food.id,
|
||||
'pageSize': 200
|
||||
}
|
||||
let options = {'pageSize': 200}
|
||||
options[this.this_recipe_param] = item.id
|
||||
|
||||
this.genericAPI(this.Models.RECIPE, this.Actions.LIST, options).then((result) => {
|
||||
parent = this.findCard(food.id, col === 'left' ? this.items_left : this.items_right)
|
||||
parent = this.findCard(item.id, this['items_' + col])
|
||||
if (parent) {
|
||||
Vue.set(parent, 'recipes', result.data.results)
|
||||
Vue.set(parent, 'show_recipes', true)
|
||||
|
@ -64,7 +64,7 @@
|
||||
</div>
|
||||
|
||||
<!-- only show scollbars in split mode -->
|
||||
<!-- weird behavior when switching to split mode, infinite scoll doesn't trigger if
|
||||
<!-- TODO: weird behavior when switching to split mode, infinite scoll doesn't trigger if
|
||||
bottom of page is in viewport can trigger by scrolling page (not column) up -->
|
||||
<div class="row" :class="{'overflow-hidden' : show_split}">
|
||||
<div class="col col-md" :class="{'mh-100 overflow-auto' : show_split}">
|
||||
@ -101,12 +101,15 @@ import _debounce from 'lodash/debounce'
|
||||
import InfiniteLoading from 'vue-infinite-loading';
|
||||
|
||||
export default {
|
||||
// TODO: this should be simplified into a Generic Infinitely Scrolling List and added as two components when split lists desired
|
||||
name: 'GenericSplitLists',
|
||||
components: {InfiniteLoading},
|
||||
props: {
|
||||
list_name: {type: String, default: 'Blank List'}, // TODO update translations to handle plural translations
|
||||
left_list: {type:Array, default(){return []}},
|
||||
left_list: {type: Array, default(){return []}},
|
||||
left_counts: {type: Object},
|
||||
right_list: {type:Array, default(){return []}},
|
||||
right_counts: {type: Object},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -116,6 +119,8 @@ export default {
|
||||
search_left: '',
|
||||
right_page: 0,
|
||||
left_page: 0,
|
||||
right_state: undefined,
|
||||
left_state: undefined,
|
||||
right: +new Date(),
|
||||
left: +new Date(),
|
||||
text: {
|
||||
@ -142,6 +147,26 @@ export default {
|
||||
this.$emit('reset', {'column':'right'})
|
||||
this.right += 1
|
||||
}, 700),
|
||||
right_counts: {
|
||||
deep: true,
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal.current >= newVal.max) {
|
||||
this.right_state.complete()
|
||||
} else {
|
||||
this.right_state.loaded()
|
||||
}
|
||||
}
|
||||
},
|
||||
left_counts: {
|
||||
deep: true,
|
||||
handler(newVal, oldVal) {
|
||||
if (newVal.current >= newVal.max) {
|
||||
this.left_state.complete()
|
||||
} else {
|
||||
this.left_state.loaded()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
resetSearch: function () {
|
||||
@ -154,16 +179,9 @@ export default {
|
||||
'page': (col==='left') ? this.left_page + 1 : this.right_page + 1,
|
||||
'column': col
|
||||
}
|
||||
// TODO: change this to be an emit and watch a prop to determine if loaded or complete
|
||||
new Promise((callback) => this.$emit('get-list', params, callback)).then((result) => {
|
||||
this[col+'_page'] += 1
|
||||
$state.loaded();
|
||||
if (!result) { // callback needs to return true if handler should continue loading more data
|
||||
$state.complete();
|
||||
}
|
||||
}).catch(() => {
|
||||
$state.complete();
|
||||
})
|
||||
this[col+'_state'] = $state
|
||||
this.$emit('get-list', params)
|
||||
this[col+'_page'] += 1
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// TODO: convert this to genericAPI
|
||||
clickUrl: function () {
|
||||
if (this.recipe !== null) {
|
||||
return resolveDjangoUrl('view_recipe', this.recipe.id)
|
||||
|
Reference in New Issue
Block a user