mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-02 20:59:28 -05:00
stubbed out all Food GenericModalForms
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* Utility CLASS to define model configurations
|
||||
* */
|
||||
import i18n from "@/i18n";
|
||||
|
||||
// TODO this needs rethought and simplified
|
||||
// maybe a function that returns a single dictionary based on action?
|
||||
@@ -25,26 +26,94 @@ export class Models {
|
||||
},
|
||||
'tree': {'default': undefined},
|
||||
},
|
||||
},
|
||||
'delete': {
|
||||
"form": {
|
||||
'instruction': {
|
||||
'form_field': true,
|
||||
'type': 'instruction',
|
||||
'function': 'translate',
|
||||
'phrase': "del_confimation_tree",
|
||||
'params':[
|
||||
{
|
||||
'token': 'source',
|
||||
'from':'item1',
|
||||
'attribute': "name"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MODELS - inherits and takes precedence over MODEL_TYPES and ACTIONS
|
||||
static FOOD = {
|
||||
'name': 'Food', // *OPTIONAL: parameters will be built model -> model_type -> default
|
||||
'model_type': this.TREE, // *OPTIONAL* model specific params for api, if not present will attempt modeltype_create then default_create
|
||||
'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
|
||||
// REQUIRED: unordered array of fields that can be set during create
|
||||
'create': {
|
||||
// if not defined partialUpdate will use the same parameters, prepending 'id'
|
||||
'params': [['name', 'description', 'recipe', 'ignore_shopping', 'supermarket_category']]
|
||||
'params': [['name', 'description', 'recipe', 'ignore_shopping', 'supermarket_category']],
|
||||
'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': ''
|
||||
},
|
||||
'recipe': {
|
||||
'form_field': true,
|
||||
'type': 'lookup',
|
||||
'field': 'recipe',
|
||||
'list': 'RECIPE',
|
||||
'label': i18n.t('Recipe')
|
||||
},
|
||||
'shopping': {
|
||||
'form_field': true,
|
||||
'type': 'checkbox',
|
||||
'field': 'ignore_shopping',
|
||||
'label': i18n.t('Ignore_Shopping')
|
||||
},
|
||||
'shopping_category': {
|
||||
'form_field': true,
|
||||
'type': 'lookup',
|
||||
'field': 'supermarket_category',
|
||||
'list': 'SHOPPING_CATEGORY',
|
||||
'label': i18n.t('Shopping_Category')
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
static KEYWORD = {}
|
||||
static KEYWORD = {
|
||||
'name': i18n.t('Keyword'), // *OPTIONAL: parameters will be built model -> model_type -> default
|
||||
'apiName': 'Keyword',
|
||||
'model_type': this.TREE
|
||||
}
|
||||
static UNIT = {}
|
||||
static RECIPE = {}
|
||||
static SHOPPING_LIST = {}
|
||||
static RECIPE_BOOK = {
|
||||
'name': i18n.t('Recipe_Book'),
|
||||
'apiName': 'RecipeBook',
|
||||
}
|
||||
static SHOPPING_CATEGORY = {
|
||||
'name': i18n.t('Shopping_Category'),
|
||||
'apiName': 'SupermarketCategory',
|
||||
}
|
||||
|
||||
static RECIPE = {
|
||||
'name': 'Recipe',
|
||||
'name': i18n.t('Recipe'),
|
||||
'apiName': 'Recipe',
|
||||
'list': {
|
||||
'params': ['query', 'keywords', 'foods', 'books', 'keywordsOr', 'foodsOr', 'booksOr', 'internal', 'random', '_new', 'page', 'pageSize', 'options'],
|
||||
'config': {
|
||||
@@ -60,14 +129,69 @@ export class Models {
|
||||
|
||||
export class Actions {
|
||||
static CREATE = {
|
||||
"function": "create"
|
||||
"function": "create",
|
||||
'form': {
|
||||
'title': {
|
||||
'function': 'translate',
|
||||
'phrase': 'create_title',
|
||||
'params' : [
|
||||
{
|
||||
'token': 'type',
|
||||
'from': 'model',
|
||||
'attribute':'name'
|
||||
}
|
||||
],
|
||||
},
|
||||
'ok_label': i18n.t('Save'),
|
||||
}
|
||||
}
|
||||
static UPDATE = {
|
||||
"function": "partialUpdate",
|
||||
// special case for update only - updated assumes create form is sufficient, but a different title is required.
|
||||
"form_title": {
|
||||
'function': 'translate',
|
||||
'phrase': 'edit_title',
|
||||
'params' : [
|
||||
{
|
||||
'token': 'type',
|
||||
'from': 'model',
|
||||
'attribute':'name'
|
||||
}
|
||||
],
|
||||
},
|
||||
}
|
||||
static DELETE = {
|
||||
"function": "destroy",
|
||||
'params': ['id']
|
||||
'params': ['id'],
|
||||
'form': {
|
||||
'title': {
|
||||
'function': 'translate',
|
||||
'phrase': 'delete_title',
|
||||
'params' : [
|
||||
{
|
||||
'token': 'type',
|
||||
'from': 'model',
|
||||
'attribute':'name'
|
||||
}
|
||||
],
|
||||
},
|
||||
'ok_label': i18n.t('Delete'),
|
||||
'instruction': {
|
||||
'form_field': true,
|
||||
'type': 'instruction',
|
||||
'label': {
|
||||
'function': 'translate',
|
||||
'phrase': "delete_confirmation",
|
||||
'params':[
|
||||
{
|
||||
'token': 'source',
|
||||
'from':'item1',
|
||||
'attribute': "name"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static FETCH = {
|
||||
"function": "retrieve",
|
||||
@@ -78,26 +202,107 @@ export class Actions {
|
||||
"suffix": "s",
|
||||
"params": ['query', 'page', 'pageSize'],
|
||||
"config": {
|
||||
'query': {'default':undefined},
|
||||
'query': {'default': undefined},
|
||||
'page': {'default': 1},
|
||||
'pageSize': {'default': 25}
|
||||
}
|
||||
|
||||
}
|
||||
static MERGE = {
|
||||
"function": "merge",
|
||||
'params': ['source', 'target'],
|
||||
"config": {
|
||||
'source': {'type':'string'},
|
||||
'source': {'type': 'string'},
|
||||
'target': {'type': 'string'}
|
||||
},
|
||||
'form': {
|
||||
'title': {
|
||||
'function': 'translate',
|
||||
'phrase': 'merge_title',
|
||||
'params' : [
|
||||
{
|
||||
'token': 'type',
|
||||
'from': 'model',
|
||||
'attribute':'name'
|
||||
}
|
||||
],
|
||||
},
|
||||
'ok_label': i18n.t('Merge'),
|
||||
'instruction': {
|
||||
'form_field': true,
|
||||
'type': 'instruction',
|
||||
'label': {
|
||||
'function': 'translate',
|
||||
'phrase': "merge_selection",
|
||||
'params':[
|
||||
{
|
||||
'token': 'source',
|
||||
'from':'item1',
|
||||
'attribute': "name"
|
||||
},
|
||||
{
|
||||
'token': 'type',
|
||||
'from':'model',
|
||||
'attribute': "name"
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
'target': {
|
||||
'form_field': true,
|
||||
'type': 'lookup',
|
||||
'field': 'target',
|
||||
'list': 'self'
|
||||
}
|
||||
}
|
||||
}
|
||||
static MOVE = {
|
||||
"function": "move",
|
||||
'params': ['source', 'target'],
|
||||
"config": {
|
||||
'source': {'type':'string'},
|
||||
'source': {'type': 'string'},
|
||||
'target': {'type': 'string'}
|
||||
},
|
||||
'form': {
|
||||
'title': {
|
||||
'function': 'translate',
|
||||
'phrase': 'move_title',
|
||||
'params' : [
|
||||
{
|
||||
'token': 'type',
|
||||
'from': 'model',
|
||||
'attribute':'name'
|
||||
}
|
||||
],
|
||||
},
|
||||
'ok_label': i18n.t('Move'),
|
||||
'instruction': {
|
||||
'form_field': true,
|
||||
'type': 'instruction',
|
||||
'label': {
|
||||
'function': 'translate',
|
||||
'phrase': "move_selection",
|
||||
'params':[
|
||||
{
|
||||
'token': 'source',
|
||||
'from':'item1',
|
||||
'attribute': "name"
|
||||
},
|
||||
{
|
||||
'token': 'type',
|
||||
'from':'model',
|
||||
'attribute': "name"
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
},
|
||||
'target': {
|
||||
'form_field': true,
|
||||
'type': 'lookup',
|
||||
'field': 'target',
|
||||
'list': 'self'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,50 +161,37 @@ import {ApiApiFactory} from "@/utils/openapi/api.ts"; // TODO: is it possible t
|
||||
import axios from "axios";
|
||||
axios.defaults.xsrfCookieName = 'csrftoken'
|
||||
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"
|
||||
export const ApiMixin = {
|
||||
methods: {
|
||||
/**
|
||||
* constructs OpenAPI Generator function using named parameters
|
||||
* @param {string} model string to define which model API to use
|
||||
* @param {string} api string to define which of the API functions to use
|
||||
* @param {object} options dictionary to define all of the parameters necessary to use API
|
||||
*/
|
||||
genericAPI: function(model, action, options) {
|
||||
let setup = getConfig(model, action)
|
||||
let func = setup.function
|
||||
let config = setup?.config ?? {}
|
||||
let params = setup?.params ?? []
|
||||
console.log('config', config, 'params', params)
|
||||
let parameters = []
|
||||
export function genericAPI(model, action, options) {
|
||||
let setup = getConfig(model, action)
|
||||
let func = setup.function
|
||||
let config = setup?.config ?? {}
|
||||
let params = setup?.params ?? []
|
||||
let parameters = []
|
||||
|
||||
let this_value = undefined
|
||||
params.forEach(function (item, index) {
|
||||
if (Array.isArray(item)) {
|
||||
this_value = {}
|
||||
// if the value is an array, convert it to a dictionary of key:value
|
||||
// filtered based on OPTIONS passed
|
||||
// maybe map/reduce is better?
|
||||
for (const [k, v] of Object.entries(options)) {
|
||||
if (item.includes(k)) {
|
||||
this_value[k] = formatParam(config?.[k], v)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this_value = options?.[item] ?? undefined
|
||||
if (this_value) {this_value = formatParam(config?.[item], this_value)}
|
||||
let this_value = undefined
|
||||
params.forEach(function (item, index) {
|
||||
if (Array.isArray(item)) {
|
||||
this_value = {}
|
||||
// if the value is an array, convert it to a dictionary of key:value
|
||||
// filtered based on OPTIONS passed
|
||||
// maybe map/reduce is better?
|
||||
for (const [k, v] of Object.entries(options)) {
|
||||
if (item.includes(k)) {
|
||||
this_value[k] = formatParam(config?.[k], v)
|
||||
}
|
||||
// if no value is found so far, get the default if it exists
|
||||
if (!this_value) {
|
||||
this_value = getDefault(config?.[item], options)
|
||||
}
|
||||
parameters.push(this_value)
|
||||
});
|
||||
|
||||
console.log(func, 'parameters', parameters, 'passed options', options)
|
||||
let apiClient = new ApiApiFactory()
|
||||
return apiClient[func](...parameters)
|
||||
},
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this_value = options?.[item] ?? undefined
|
||||
if (this_value) {this_value = formatParam(config?.[item], this_value)}
|
||||
}
|
||||
// if no value is found so far, get the default if it exists
|
||||
if (!this_value) {
|
||||
this_value = getDefault(config?.[item], options)
|
||||
}
|
||||
parameters.push(this_value)
|
||||
});
|
||||
let apiClient = new ApiApiFactory()
|
||||
return apiClient[func](...parameters)
|
||||
}
|
||||
|
||||
// /*
|
||||
@@ -258,7 +245,6 @@ function getDefault(config, options) {
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
function getConfig(model, action) {
|
||||
let f = action.function
|
||||
// if not defined partialUpdate will use params from create
|
||||
@@ -268,21 +254,84 @@ function getConfig(model, action) {
|
||||
|
||||
let config = {
|
||||
'name': model.name,
|
||||
'function': f + model.name + action?.suffix
|
||||
'apiName': model.apiName,
|
||||
}
|
||||
// spread operator merges dictionaries - last item in list takes precedence
|
||||
config = {...config, ...action, ...model.model_type?.[f], ...model?.[f]}
|
||||
// nested dictionaries are not merged - so merge again on any nested keys
|
||||
config.config = {...action?.config, ...model.model_type?.[f]?.config, ...model?.[f]?.config}
|
||||
config.function = config.function + config.name + (config?.suffix ?? '') // parens are required to force optional chaining to evaluate before concat
|
||||
config['function'] = f + config.apiName + (config?.suffix ?? '') // parens are required to force optional chaining to evaluate before concat
|
||||
return config
|
||||
}
|
||||
|
||||
// /*
|
||||
// * functions for Generic Modal Forms
|
||||
// * */
|
||||
export function getForm(model, action, item1, item2) {
|
||||
let f = action.function
|
||||
let config = {...action?.form, ...model.model_type?.[f]?.form, ...model?.[f]?.form}
|
||||
// if not defined partialUpdate will use form from create
|
||||
if (f === 'partialUpdate' && Object.keys(config).length == 0) {
|
||||
console.log('create form',Actions.CREATE?.form)
|
||||
config = {...Actions.CREATE?.form, ...model.model_type?.['create']?.form, ...model?.['create']?.form}
|
||||
config['title'] = {...action?.form_title, ...model.model_type?.[f]?.form_title, ...model?.[f]?.form_title}
|
||||
}
|
||||
let form = {'fields': []}
|
||||
let value = ''
|
||||
for (const [k, v] of Object.entries(config)) {
|
||||
if (v?.function){
|
||||
switch(v.function) {
|
||||
case 'translate':
|
||||
value = formTranslate(v, model, item1, item2)
|
||||
}
|
||||
} else {
|
||||
value = v
|
||||
}
|
||||
if (value?.form_field) {
|
||||
form.fields.push(
|
||||
{
|
||||
...value,
|
||||
...{
|
||||
'label': formTranslate(value?.label, model, item1, item2),
|
||||
'placeholder': formTranslate(value?.placeholder, model, item1, item2)
|
||||
}
|
||||
}
|
||||
)
|
||||
} else {
|
||||
form[k] = value
|
||||
}
|
||||
}
|
||||
console.log('utils form', form)
|
||||
return form
|
||||
|
||||
}
|
||||
function formTranslate(translate, model, item1, item2) {
|
||||
if (typeof(translate) !== 'object') {return translate}
|
||||
let phrase = translate.phrase
|
||||
let options = {}
|
||||
let obj = undefined
|
||||
translate?.params.forEach(function (x, index) {
|
||||
switch(x.from){
|
||||
case 'item1':
|
||||
obj = item1
|
||||
break;
|
||||
case 'item2':
|
||||
obj = item2
|
||||
break;
|
||||
case 'model':
|
||||
obj = model
|
||||
}
|
||||
options[x.token] = obj[x.attribute]
|
||||
})
|
||||
return i18n.t(phrase, options)
|
||||
|
||||
}
|
||||
|
||||
// /*
|
||||
// * Utility functions to use manipulate nested components
|
||||
// * */
|
||||
import Vue from 'vue'
|
||||
import { Actions } from './models';
|
||||
export const CardMixin = {
|
||||
methods: {
|
||||
findCard: function(id, card_list){
|
||||
@@ -335,7 +384,6 @@ export const CardMixin = {
|
||||
}
|
||||
} else {
|
||||
idx = card_list.indexOf(card_list.find(x => x.id === target.id))
|
||||
console.log(card_list, idx, obj)
|
||||
Vue.set(card_list, idx, obj)
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user