Continue converting to composition api
This commit is contained in:
parent
a071e6b21e
commit
0d35f50dbf
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import { computed, nextTick, useTemplateRef, watch } from "vue";
|
import { computed, nextTick, onMounted, onUpdated, useTemplateRef } from "vue";
|
||||||
|
|
||||||
import Caret from "../iconic/svg/smart/caret";
|
import Caret from "../iconic/svg/smart/caret";
|
||||||
import Check from "../iconic/svg/smart/check";
|
import Check from "../iconic/svg/smart/check";
|
||||||
@ -130,14 +130,18 @@
|
|||||||
svgElement.value.update();
|
svgElement.value.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
function updateScripts() {
|
||||||
() => props.icon,
|
|
||||||
() => {
|
|
||||||
ensureSvgApi(svgName.value, svgData.value.scriptBlocks);
|
ensureSvgApi(svgName.value, svgData.value.scriptBlocks);
|
||||||
nextTick(() => setupSvgApi(svgName.value));
|
setupSvgApi(svgName.value);
|
||||||
},
|
}
|
||||||
{ immediate: true }
|
|
||||||
);
|
onMounted(() => {
|
||||||
|
updateScripts();
|
||||||
|
});
|
||||||
|
|
||||||
|
onUpdated(() => {
|
||||||
|
updateScripts();
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
svgData,
|
svgData,
|
||||||
|
@ -11,10 +11,13 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
export default {
|
import { computed } from "vue";
|
||||||
props: {
|
|
||||||
|
const emit = defineEmits(["changePage"]);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
pagedItemName: {
|
pagedItemName: {
|
||||||
required: false,
|
required: false,
|
||||||
type: String,
|
type: String,
|
||||||
@ -48,19 +51,18 @@
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
computed: {
|
const pageItems = computed(() => {
|
||||||
pageItems() {
|
|
||||||
const items = new Set();
|
const items = new Set();
|
||||||
|
|
||||||
for (let x = 0; x < this.pageOuterWindow; x++) {
|
for (let x = 0; x < props.pageOuterWindow; x++) {
|
||||||
items.add(x + 1);
|
items.add(x + 1);
|
||||||
items.add(this.totalPages - x);
|
items.add(props.totalPages - x);
|
||||||
}
|
}
|
||||||
|
|
||||||
const start = this.currentPage - Math.ceil(this.pageWindow / 2);
|
const start = props.currentPage - Math.ceil(props.pageWindow / 2);
|
||||||
const end = this.currentPage + Math.floor(this.pageWindow / 2);
|
const end = props.currentPage + Math.floor(props.pageWindow / 2);
|
||||||
|
|
||||||
for (let x = start; x <= end; x++) {
|
for (let x = start; x <= end; x++) {
|
||||||
items.add(x);
|
items.add(x);
|
||||||
@ -69,7 +71,7 @@
|
|||||||
let emptySpace = -1;
|
let emptySpace = -1;
|
||||||
const finalList = [];
|
const finalList = [];
|
||||||
|
|
||||||
[...items.values()].filter(p => p > 0 && p <= this.totalPages).sort((a, b) => a - b).forEach((p, idx, list) => {
|
[...items.values()].filter(p => p > 0 && p <= props.totalPages).sort((a, b) => a - b).forEach((p, idx, list) => {
|
||||||
finalList.push(p);
|
finalList.push(p);
|
||||||
if (list[idx + 1] && list[idx + 1] !== p + 1) {
|
if (list[idx + 1] && list[idx + 1] !== p + 1) {
|
||||||
finalList.push(emptySpace--);
|
finalList.push(emptySpace--);
|
||||||
@ -77,30 +79,13 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
return finalList;
|
return finalList;
|
||||||
},
|
});
|
||||||
|
|
||||||
isLastPage() {
|
const isLastPage = computed(() => props.currentPage === props.totalPages);
|
||||||
return this.currentPage === this.totalPages;
|
const isFirstPage = computed(() => props.currentPage === 1);
|
||||||
},
|
|
||||||
|
|
||||||
isFirstPage() {
|
function changePage(idx) {
|
||||||
return this.currentPage === 1;
|
emit("changePage", idx);
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
changePage(idx) {
|
|
||||||
this.$emit("changePage", idx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
ul.pagination {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
@ -9,11 +9,13 @@
|
|||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
|
import { computed, ref, useTemplateRef } from "vue";
|
||||||
|
|
||||||
export default {
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
props: {
|
|
||||||
|
const props = defineProps({
|
||||||
starCount: {
|
starCount: {
|
||||||
required: false,
|
required: false,
|
||||||
type: Number,
|
type: Number,
|
||||||
@ -37,68 +39,54 @@
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 0
|
default: 0
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
data() {
|
const temporaryValue = ref(null);
|
||||||
return {
|
const ratingPercent = computed(() => ((props.modelValue || 0) / props.starCount) * 100.0);
|
||||||
temporaryValue: null
|
const wrapperEl = useTemplateRef("wrapper");
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
const temporaryPercent = computed(() => {
|
||||||
ratingPercent() {
|
if (temporaryValue.value !== null) {
|
||||||
return ((this.modelValue || 0) / this.starCount) * 100.0;
|
return (temporaryValue.value / props.starCount) * 100.0;
|
||||||
},
|
|
||||||
|
|
||||||
temporaryPercent() {
|
|
||||||
if (this.temporaryValue !== null) {
|
|
||||||
return (this.temporaryValue / this.starCount) * 100.0;
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
filledStyle() {
|
const filledStyle = computed(() => {
|
||||||
const width = this.temporaryPercent || this.ratingPercent;
|
const width = temporaryPercent.value || ratingPercent.value;
|
||||||
return {
|
return {
|
||||||
width: width + "%"
|
width: width + "%"
|
||||||
};
|
};
|
||||||
}
|
});
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
function handleClick(evt) {
|
||||||
handleClick(evt) {
|
if (temporaryValue.value !== null) {
|
||||||
if (this.temporaryValue !== null) {
|
emit("update:modelValue", temporaryValue.value);
|
||||||
this.$emit("update:modelValue", this.temporaryValue);
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
handleMousemove(evt) {
|
function handleMousemove(evt) {
|
||||||
if (this.readonly) {
|
if (props.readonly) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wrapperBox = this.$refs.wrapper.getBoundingClientRect();
|
const wrapperBox = wrapperEl.value.getBoundingClientRect();
|
||||||
const wrapperWidth = wrapperBox.right - wrapperBox.left;
|
const wrapperWidth = wrapperBox.right - wrapperBox.left;
|
||||||
const mousePosition = evt.clientX;
|
const mousePosition = evt.clientX;
|
||||||
|
|
||||||
if (mousePosition > wrapperBox.left && mousePosition < wrapperBox.right) {
|
if (mousePosition > wrapperBox.left && mousePosition < wrapperBox.right) {
|
||||||
const filledRatio = ((mousePosition - wrapperBox.left) / wrapperWidth);
|
const filledRatio = ((mousePosition - wrapperBox.left) / wrapperWidth);
|
||||||
|
|
||||||
const totalSteps = this.starCount / this.step;
|
const totalSteps = props.starCount / props.step;
|
||||||
const filledSteps = Math.round(totalSteps * filledRatio);
|
const filledSteps = Math.round(totalSteps * filledRatio);
|
||||||
|
|
||||||
this.temporaryValue = filledSteps * this.step;
|
temporaryValue.value = filledSteps * props.step;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
handleMouseleave(evt) {
|
function handleMouseleave(evt) {
|
||||||
this.temporaryValue = null;
|
temporaryValue.value = null;
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -6,12 +6,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
|
import { ref } from "vue";
|
||||||
import debounce from "lodash/debounce";
|
import debounce from "lodash/debounce";
|
||||||
|
|
||||||
export default {
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
props: {
|
|
||||||
|
const props = defineProps({
|
||||||
placeholder: {
|
placeholder: {
|
||||||
required: false,
|
required: false,
|
||||||
type: String,
|
type: String,
|
||||||
@ -23,44 +25,26 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: ""
|
default: ""
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const text = ref(null);
|
||||||
|
|
||||||
|
const triggerInput = debounce(function() {
|
||||||
|
emit("update:modelValue", text.value);
|
||||||
},
|
},
|
||||||
|
250,
|
||||||
|
{ leading: false, trailing: true })
|
||||||
|
|
||||||
data() {
|
function userUpdateText(newText) {
|
||||||
return {
|
if (text.value !== newText) {
|
||||||
text: null
|
text.value = newText;
|
||||||
};
|
triggerInput();
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
triggerInput: debounce(function() {
|
|
||||||
this.$emit("update:modelValue", this.text);
|
|
||||||
}, 250, {leading: false, trailing: true}),
|
|
||||||
|
|
||||||
userUpdateText(text) {
|
|
||||||
if (this.text !== text) {
|
|
||||||
this.text = text;
|
|
||||||
this.triggerInput();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
propUpdateText(text) {
|
|
||||||
if (this.text === null && this.text !== text) {
|
|
||||||
this.text = text;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
function propUpdateText(newText) {
|
||||||
this.$watch("modelValue",
|
if (text.value === null && text.value !== newText) {
|
||||||
val => this.propUpdateText(val),
|
text.value = newText;
|
||||||
{
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,42 +7,33 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
export default {
|
import {computed, nextTick, ref, useTemplateRef} from "vue";
|
||||||
props: {
|
|
||||||
|
const emit = defineEmits(["update:modelValue"]);
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Array
|
type: Array
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
data() {
|
const hasFocus = ref(false);
|
||||||
return {
|
const tagText = computed(() => props.modelValue.join(" "));
|
||||||
hasFocus: false
|
const inputElement = useTemplateRef("input");
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
function inputHandler(el) {
|
||||||
tagText() {
|
|
||||||
return this.modelValue.join(" ");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
inputHandler(el) {
|
|
||||||
let str = el.target.value;
|
let str = el.target.value;
|
||||||
this.checkInput(str);
|
checkInput(str);
|
||||||
this.$nextTick(() => {
|
nextTick(() => {
|
||||||
el.target.value = str;
|
el.target.value = str;
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
checkInput(str) {
|
function checkInput(str) {
|
||||||
if (this.hasFocus) {
|
if (hasFocus.value) {
|
||||||
const m = str.match(/\S\s+\S*$/);
|
const m = str.match(/\S\s+\S*$/);
|
||||||
|
|
||||||
if (m !== null) {
|
if (m !== null) {
|
||||||
@ -54,22 +45,21 @@
|
|||||||
|
|
||||||
const newTags = [...new Set(str.toString().split(/\s+/).filter(t => t.length > 0))];
|
const newTags = [...new Set(str.toString().split(/\s+/).filter(t => t.length > 0))];
|
||||||
|
|
||||||
if (!this.arraysEqual(newTags, this.modelValue)) {
|
if (!arraysEqual(newTags, props.modelValue)) {
|
||||||
this.$emit("update:modelValue", newTags);
|
emit("update:modelValue", newTags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
getFocus() {
|
function getFocus() {
|
||||||
this.hasFocus = true;
|
hasFocus.value = true;
|
||||||
},
|
}
|
||||||
|
|
||||||
loseFocus() {
|
function loseFocus() {
|
||||||
this.hasFocus = false;
|
hasFocus.value = false;
|
||||||
this.checkInput(this.$refs.input.value);
|
checkInput(inputElement.value.value);
|
||||||
|
}
|
||||||
|
|
||||||
},
|
function arraysEqual(arr1, arr2) {
|
||||||
|
|
||||||
arraysEqual(arr1, arr2) {
|
|
||||||
if(arr1.length !== arr2.length)
|
if(arr1.length !== arr2.length)
|
||||||
return false;
|
return false;
|
||||||
for(let i = arr1.length; i--;) {
|
for(let i = arr1.length; i--;) {
|
||||||
@ -79,7 +69,4 @@
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
@ -2,8 +2,8 @@
|
|||||||
<div class="field">
|
<div class="field">
|
||||||
<label v-if="label.length" class="label is-small-mobile">{{ label }}</label>
|
<label v-if="label.length" class="label is-small-mobile">{{ label }}</label>
|
||||||
<div :class="controlClasses">
|
<div :class="controlClasses">
|
||||||
<textarea v-if="isTextarea" :class="inputClasses" :value="modelValue" @input="input" :disabled="disabled"></textarea>
|
<textarea v-if="isTextarea" :class="inputClasses" v-model="model" :disabled="disabled"></textarea>
|
||||||
<input v-else :type="type" :class="inputClasses" :value="modelValue" @input="input" :disabled="disabled">
|
<input v-else :type="type" :class="inputClasses" v-model="model" :disabled="disabled">
|
||||||
<app-icon class="is-right" icon="warning" v-if="validationError !== null"></app-icon>
|
<app-icon class="is-right" icon="warning" v-if="validationError !== null"></app-icon>
|
||||||
</div>
|
</div>
|
||||||
<p v-if="helpMessage !== null" :class="helpClasses">
|
<p v-if="helpMessage !== null" :class="helpClasses">
|
||||||
@ -12,10 +12,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
export default {
|
import { computed } from "vue";
|
||||||
props: {
|
|
||||||
|
const props = defineProps({
|
||||||
label: {
|
label: {
|
||||||
required: false,
|
required: false,
|
||||||
type: String,
|
type: String,
|
||||||
@ -40,53 +41,38 @@
|
|||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
computed: {
|
const model = defineModel({
|
||||||
isTextarea() {
|
type: [String, Number],
|
||||||
return this.type === "textarea";
|
default: ""
|
||||||
},
|
});
|
||||||
|
|
||||||
controlClasses() {
|
const isTextarea = computed(() => props.type === "textarea");
|
||||||
return [
|
const controlClasses = computed(() => [
|
||||||
"control",
|
"control",
|
||||||
{
|
{
|
||||||
"has-icons-right": this.validationError !== null
|
"has-icons-right": props.validationError !== null
|
||||||
}
|
}
|
||||||
]
|
]);
|
||||||
},
|
|
||||||
|
|
||||||
inputClasses() {
|
const inputClasses = computed(() =>[
|
||||||
return [
|
|
||||||
"is-small-mobile",
|
"is-small-mobile",
|
||||||
{
|
{
|
||||||
"textarea": this.isTextarea,
|
"textarea": isTextarea.value,
|
||||||
"input": !this.isTextarea,
|
"input": !isTextarea.value,
|
||||||
"is-danger": this.validationError !== null
|
"is-danger": props.validationError !== null
|
||||||
}
|
}
|
||||||
]
|
]);
|
||||||
},
|
|
||||||
|
|
||||||
helpMessage() {
|
const helpMessage = computed(() => props.validationError);
|
||||||
return this.validationError;
|
const helpClasses = computed(() => [
|
||||||
},
|
|
||||||
|
|
||||||
helpClasses() {
|
|
||||||
return [
|
|
||||||
"help",
|
"help",
|
||||||
{
|
{
|
||||||
"is-danger": this.validationError !== null
|
"is-danger": props.validationError !== null
|
||||||
}
|
}
|
||||||
];
|
]);
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
input(evt) {
|
|
||||||
this.$emit("update:modelValue", evt.target.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -6,16 +6,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
props: {
|
|
||||||
errors: {
|
errors: {
|
||||||
required: false,
|
required: false,
|
||||||
type: Object,
|
type: Object,
|
||||||
default: {}
|
default: {}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
@ -144,14 +144,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
|
import { computed } from "vue";
|
||||||
import api from "../lib/Api";
|
import api from "../lib/Api";
|
||||||
import { mapState } from "pinia";
|
import { mapState } from "pinia";
|
||||||
import { useNutrientStore } from "../stores/nutrient";
|
import { useNutrientStore } from "../stores/nutrient";
|
||||||
|
import { useLoadResource } from "../lib/useLoadResource";
|
||||||
|
|
||||||
export default {
|
const nutrientStore = useNutrientStore();
|
||||||
props: {
|
const nutrients = computed(() => nutrientStore.nutrientList);
|
||||||
|
const { loadResource } = useLoadResource();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
food: {
|
food: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
@ -166,53 +171,35 @@
|
|||||||
type: String,
|
type: String,
|
||||||
default: "Editing"
|
default: "Editing"
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
data() {
|
const visibleFoodUnits = computed(() => props.food.food_units.filter(iu => iu._destroy !== true));
|
||||||
return {
|
const hasNdbn = computed(() => props.food.ndbn !== null);
|
||||||
|
|
||||||
};
|
function addUnit() {
|
||||||
},
|
props.food.food_units.push({
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(useNutrientStore, {
|
|
||||||
nutrients: 'nutrientList'
|
|
||||||
}),
|
|
||||||
|
|
||||||
visibleFoodUnits() {
|
|
||||||
return this.food.food_units.filter(iu => iu._destroy !== true);
|
|
||||||
},
|
|
||||||
|
|
||||||
hasNdbn() {
|
|
||||||
return this.food.ndbn !== null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
addUnit() {
|
|
||||||
this.food.food_units.push({
|
|
||||||
id: null,
|
id: null,
|
||||||
name: null,
|
name: null,
|
||||||
gram_weight: null
|
gram_weight: null
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
|
|
||||||
removeUnit(unit) {
|
function removeUnit(unit) {
|
||||||
if (unit.id) {
|
if (unit.id) {
|
||||||
unit._destroy = true;
|
unit._destroy = true;
|
||||||
} else {
|
} else {
|
||||||
const idx = this.food.food_units.findIndex(i => i === unit);
|
const idx = props.food.food_units.findIndex(i => i === unit);
|
||||||
this.food.food_units.splice(idx, 1);
|
props.food.food_units.splice(idx, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
removeNdbn() {
|
function removeNdbn() {
|
||||||
this.food.ndbn = null;
|
props.food.ndbn = null;
|
||||||
this.food.usda_food_name = null;
|
props.food.usda_food_name = null;
|
||||||
this.food.ndbn_units = [];
|
props.food.ndbn_units = [];
|
||||||
},
|
}
|
||||||
|
|
||||||
updateSearchItems(text) {
|
function updateSearchItems(text) {
|
||||||
return api.getUsdaFoodSearch(text)
|
return api.getUsdaFoodSearch(text)
|
||||||
.then(data => data.map(f => {
|
.then(data => data.map(f => {
|
||||||
return {
|
return {
|
||||||
@ -221,23 +208,18 @@
|
|||||||
description: ["#", f.ndbn, ", Cal:", f.kcal, ", Carbs:", f.carbohydrates, ", Fat:", f.lipid, ", Protein:", f.protein].join("")
|
description: ["#", f.ndbn, ", Cal:", f.kcal, ", Carbs:", f.carbohydrates, ", Fat:", f.lipid, ", Protein:", f.protein].join("")
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
},
|
}
|
||||||
|
|
||||||
searchItemSelected(food) {
|
function searchItemSelected(food) {
|
||||||
this.food.ndbn = food.ndbn;
|
props.food.ndbn = food.ndbn;
|
||||||
this.food.usda_food_name = food.name;
|
props.food.usda_food_name = food.name;
|
||||||
this.food.ndbn_units = [];
|
props.food.ndbn_units = [];
|
||||||
|
|
||||||
this.loadResource(
|
loadResource(
|
||||||
api.postIngredientSelectNdbn(this.food)
|
api.postIngredientSelectNdbn(props.food)
|
||||||
.then(i => Object.assign(this.food, i))
|
.then(i => Object.assign(props.food, i))
|
||||||
);
|
);
|
||||||
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -53,25 +53,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
import { mapState } from "pinia";
|
import { computed } from "vue";
|
||||||
import { useNutrientStore } from "../stores/nutrient";
|
import { useNutrientStore } from "../stores/nutrient";
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
props: {
|
|
||||||
food: {
|
food: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
computed: {
|
const nutrientStore = useNutrientStore();
|
||||||
...mapState(useNutrientStore, {
|
const nutrients = computed(() => nutrientStore.nutrientList);
|
||||||
nutrients: 'nutrientList'
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -31,12 +31,11 @@
|
|||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
import RecipeEdit from "./RecipeEdit";
|
import RecipeEdit from "./RecipeEdit";
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
props: {
|
|
||||||
log: {
|
log: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
@ -46,12 +45,7 @@
|
|||||||
type: Object,
|
type: Object,
|
||||||
default: {}
|
default: {}
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
|
|
||||||
components: {
|
|
||||||
RecipeEdit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -44,22 +44,16 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
import RecipeShow from "./RecipeShow";
|
import RecipeShow from "./RecipeShow";
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
props: {
|
|
||||||
log: {
|
log: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
components: {
|
|
||||||
RecipeShow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -19,36 +19,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
export default {
|
import { computed } from "vue";
|
||||||
props: {
|
|
||||||
|
const emit = defineEmits(["save", "cancel"]);
|
||||||
|
const props = defineProps({
|
||||||
note: {
|
note: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
data() {
|
const canSave = computed(() => props.note?.content?.length);
|
||||||
return {
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
function save() {
|
||||||
canSave() {
|
emit("save", props.note);
|
||||||
return this.note && this.note.content && this.note.content.length;
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
function cancel() {
|
||||||
save() {
|
emit("cancel");
|
||||||
this.$emit("save", this.note);
|
|
||||||
},
|
|
||||||
|
|
||||||
cancel() {
|
|
||||||
this.$emit("cancel");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -206,16 +206,15 @@ _underline_
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
|
import { computed, ref, watch } from "vue";
|
||||||
//import autosize from "autosize";
|
//import autosize from "autosize";
|
||||||
import debounce from "lodash/debounce";
|
import debounce from "lodash/debounce";
|
||||||
import api from "../lib/Api";
|
import api from "../lib/Api";
|
||||||
|
|
||||||
import RecipeEditIngredientEditor from "./RecipeEditIngredientEditor";
|
import RecipeEditIngredientEditor from "./RecipeEditIngredientEditor";
|
||||||
|
|
||||||
export default {
|
const props = defineProps({
|
||||||
props: {
|
|
||||||
recipe: {
|
recipe: {
|
||||||
required: true,
|
required: true,
|
||||||
type: Object
|
type: Object
|
||||||
@ -225,48 +224,29 @@ _underline_
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
data() {
|
const stepPreviewCache = ref(null);
|
||||||
return {
|
const isDescriptionHelpOpen = ref(false);
|
||||||
stepPreviewCache: null,
|
|
||||||
isDescriptionHelpOpen: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
const stepPreview = computed(() => {
|
||||||
stepPreview() {
|
if (stepPreviewCache.value === null) {
|
||||||
if (this.stepPreviewCache === null) {
|
return props.recipe.rendered_steps;
|
||||||
return this.recipe.rendered_steps;
|
|
||||||
} else {
|
} else {
|
||||||
return this.stepPreviewCache;
|
return stepPreviewCache.value;
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
const updatePreview = debounce(function() {
|
||||||
|
api.postPreviewSteps(props.recipe.step_text)
|
||||||
|
.then(data => stepPreviewCache.value = data.rendered_steps)
|
||||||
|
.catch(err => stepPreviewCache.value = "?? Error ??");
|
||||||
|
}, 750);
|
||||||
|
|
||||||
updatePreview: debounce(function() {
|
watch(
|
||||||
api.postPreviewSteps(this.recipe.step_text)
|
() => props.recipe.step_text,
|
||||||
.then(data => this.stepPreviewCache = data.rendered_steps)
|
() => updatePreview()
|
||||||
.catch(err => this.stepPreviewCache = "?? Error ??");
|
);
|
||||||
}, 750)
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
'recipe.step_text': function() {
|
|
||||||
this.updatePreview();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
//autosize(this.$refs.step_text_area);
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
RecipeEditIngredientEditor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div>
|
<div>
|
||||||
<h1 class="title">Recipes</h1>
|
<h1 class="title">Recipes</h1>
|
||||||
|
|
||||||
<router-link v-if="isLoggedIn" :to="{name: 'new_recipe'}" class="button is-primary">Create Recipe</router-link>
|
<router-link v-if="appConfig.isLoggedIn" :to="{name: 'new_recipe'}" class="button is-primary">Create Recipe</router-link>
|
||||||
|
|
||||||
<app-pager :current-page="currentPage" :total-pages="totalPages" paged-item-name="recipe" @changePage="changePage"></app-pager>
|
<app-pager :current-page="currentPage" :total-pages="totalPages" paged-item-name="recipe" @changePage="changePage"></app-pager>
|
||||||
|
|
||||||
@ -25,10 +25,10 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<app-search-text placeholder="search names" :value="search.name" @input="setSearchName($event)"></app-search-text>
|
<app-search-text placeholder="search names" :value="search.name" @update:modelValue="setSearchName($event)"></app-search-text>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<app-search-text placeholder="search tags" :value="search.tags" @input="setSearchTags($event)"></app-search-text>
|
<app-search-text placeholder="search tags" :value="search.tags" @update:modelValue="setSearchTags($event)"></app-search-text>
|
||||||
</td>
|
</td>
|
||||||
<td colspan="5"></td>
|
<td colspan="5"></td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -49,10 +49,12 @@
|
|||||||
<td class="recipe-time">{{ formatRecipeTime(r.total_time, r.active_time) }}</td>
|
<td class="recipe-time">{{ formatRecipeTime(r.total_time, r.active_time) }}</td>
|
||||||
<td><app-date-time :date-time="r.created_at" :show-time="false"></app-date-time></td>
|
<td><app-date-time :date-time="r.created_at" :show-time="false"></app-date-time></td>
|
||||||
<td>
|
<td>
|
||||||
<app-dropdown hover v-if="isLoggedIn" class="is-right">
|
<app-dropdown hover v-if="appConfig.isLoggedIn" class="is-right">
|
||||||
<button slot="button" class="button is-small">
|
<template #button>
|
||||||
|
<button class="button is-small">
|
||||||
<app-icon icon="menu"></app-icon>
|
<app-icon icon="menu"></app-icon>
|
||||||
</button>
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="dropdown-item">
|
<div class="dropdown-item">
|
||||||
<router-link :to="{name: 'new_log', params: { recipeId: r.id } }" class="button is-primary is-fullwidth">
|
<router-link :to="{name: 'new_log', params: { recipeId: r.id } }" class="button is-primary is-fullwidth">
|
||||||
@ -88,106 +90,109 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script setup>
|
||||||
|
|
||||||
|
import { computed, reactive, ref, watch } from "vue";
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
import api from "../lib/Api";
|
import api from "../lib/Api";
|
||||||
import { mapWritableState, mapState } from "pinia";
|
|
||||||
import AppLoading from "./AppLoading";
|
import AppLoading from "./AppLoading";
|
||||||
import { useAppConfigStore } from "../stores/appConfig";
|
import { useAppConfigStore } from "../stores/appConfig";
|
||||||
import { useMediaQueryStore } from "../stores/mediaQuery";
|
import { useMediaQueryStore } from "../stores/mediaQuery";
|
||||||
|
import { useLoadResource } from "../lib/useLoadResource";
|
||||||
|
|
||||||
export default {
|
const appConfig = useAppConfigStore();
|
||||||
props: {
|
const mediaQueries = useMediaQueryStore();
|
||||||
|
const { loadResource, localLoading } = useLoadResource();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
searchQuery: {
|
searchQuery: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: false,
|
required: false,
|
||||||
default: {}
|
default: {}
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
|
|
||||||
data() {
|
const tableHeader = [
|
||||||
return {
|
|
||||||
recipeData: null,
|
|
||||||
recipeForDeletion: null
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(useMediaQueryStore, { isTouch: store => store.touch }),
|
|
||||||
...mapWritableState(useAppConfigStore, [
|
|
||||||
"initialLoad"
|
|
||||||
]),
|
|
||||||
|
|
||||||
search() {
|
|
||||||
return {
|
|
||||||
name: this.searchQuery.name || null,
|
|
||||||
tags: this.searchQuery.tags || null,
|
|
||||||
column: this.searchQuery.column || "created_at",
|
|
||||||
direction: this.searchQuery.direction || "desc",
|
|
||||||
page: this.searchQuery.page || 1,
|
|
||||||
per: this.searchQuery.per || 25
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
recipes() {
|
|
||||||
if (this.recipeData) {
|
|
||||||
return this.recipeData.recipes;
|
|
||||||
} else {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
tableHeader() {
|
|
||||||
return [
|
|
||||||
{name: 'name', label: 'Name', sort: true},
|
{name: 'name', label: 'Name', sort: true},
|
||||||
{name: 'tags', label: 'Tags', sort: false},
|
{name: 'tags', label: 'Tags', sort: false},
|
||||||
{name: 'rating', label: 'Rating', sort: true},
|
{name: 'rating', label: 'Rating', sort: true},
|
||||||
{name: 'yields', label: 'Yields', sort: false},
|
{name: 'yields', label: 'Yields', sort: false},
|
||||||
{name: 'total_time', label: 'Time', sort: true},
|
{name: 'total_time', label: 'Time', sort: true},
|
||||||
{name: 'created_at', label: 'Created', sort: true}
|
{name: 'created_at', label: 'Created', sort: true}
|
||||||
]
|
];
|
||||||
},
|
|
||||||
|
|
||||||
totalPages() {
|
const recipeData = ref(null);
|
||||||
if (this.recipeData) {
|
const recipeForDeletion = ref(null);
|
||||||
return this.recipeData.total_pages;
|
const isTouch = computed(() => mediaQueries.touch);
|
||||||
|
|
||||||
|
const search = computed(() => ({
|
||||||
|
name: props.searchQuery.name || null,
|
||||||
|
tags: props.searchQuery.tags || null,
|
||||||
|
column: props.searchQuery.column || "created_at",
|
||||||
|
direction: props.searchQuery.direction || "desc",
|
||||||
|
page: props.searchQuery.page || 1,
|
||||||
|
per: props.searchQuery.per || 25
|
||||||
|
}));
|
||||||
|
|
||||||
|
const recipes = computed(() => {
|
||||||
|
if (recipeData.value) {
|
||||||
|
return recipeData.value.recipes;
|
||||||
|
} else {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalPages = computed(() => {
|
||||||
|
if (recipeData.value) {
|
||||||
|
return recipeData.value.total_pages;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
},
|
});
|
||||||
|
|
||||||
currentPage() {
|
const currentPage = computed(() => {
|
||||||
if (this.recipeData) {
|
if (recipeData.value) {
|
||||||
return this.recipeData.current_page;
|
return recipeData.value.current_page;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
},
|
});
|
||||||
|
|
||||||
showConfirmRecipeDelete() {
|
const showConfirmRecipeDelete = computed(() => recipeForDeletion.value !== null);
|
||||||
return this.recipeForDeletion !== null;
|
|
||||||
},
|
|
||||||
|
|
||||||
confirmRecipeDeleteMessage() {
|
const confirmRecipeDeleteMessage = computed(() => {
|
||||||
if (this.showConfirmRecipeDelete) {
|
if (showConfirmRecipeDelete.value) {
|
||||||
return `Are you sure you want to delete ${this.recipeForDeletion.name}?`;
|
return `Are you sure you want to delete ${recipeForDeletion.value.name}?`;
|
||||||
} else {
|
} else {
|
||||||
return "??";
|
return "??";
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
watch(search, () => {
|
||||||
buildQueryParams() {
|
getList().then(() => appConfig.initialLoad = true);
|
||||||
|
}, {
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
});
|
||||||
|
|
||||||
|
function getList() {
|
||||||
|
return loadResource(
|
||||||
|
api.getRecipeList(search.value.page, search.value.per, search.value.column, search.value.direction, search.value.name, search.value.tags, data => recipeData.value = data)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function buildQueryParams() {
|
||||||
return {
|
return {
|
||||||
name: this.searchQuery.name,
|
name: props.searchQuery.name,
|
||||||
tags: this.searchQuery.tags,
|
tags: props.searchQuery.tags,
|
||||||
column: this.searchQuery.column,
|
column: props.searchQuery.column,
|
||||||
direction: this.searchQuery.direction,
|
direction: props.searchQuery.direction,
|
||||||
page: this.searchQuery.page,
|
page: props.searchQuery.page,
|
||||||
per: this.searchQuery.per
|
per: props.searchQuery.per
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
redirectToParams(params) {
|
function redirectToParams(params) {
|
||||||
const rParams = {};
|
const rParams = {};
|
||||||
|
|
||||||
if (params.name) {
|
if (params.name) {
|
||||||
@ -214,17 +219,17 @@
|
|||||||
rParams.per = params.per;
|
rParams.per = params.per;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$router.push({name: 'recipeList', query: rParams});
|
router.push({name: 'recipeList', query: rParams});
|
||||||
},
|
}
|
||||||
|
|
||||||
changePage(idx) {
|
function changePage(idx) {
|
||||||
const p = this.buildQueryParams();
|
const p = buildQueryParams();
|
||||||
p.page = idx;
|
p.page = idx;
|
||||||
this.redirectToParams(p);
|
redirectToParams(p);
|
||||||
},
|
}
|
||||||
|
|
||||||
setSort(col) {
|
function setSort(col) {
|
||||||
const p = this.buildQueryParams();
|
const p = buildQueryParams();
|
||||||
|
|
||||||
if (p.column === col) {
|
if (p.column === col) {
|
||||||
p.direction = p.direction === "desc" ? "asc" : "desc";
|
p.direction = p.direction === "desc" ? "asc" : "desc";
|
||||||
@ -232,53 +237,47 @@
|
|||||||
p.column = col;
|
p.column = col;
|
||||||
p.direction = "asc";
|
p.direction = "asc";
|
||||||
}
|
}
|
||||||
this.redirectToParams(p);
|
redirectToParams(p);
|
||||||
},
|
}
|
||||||
|
|
||||||
setSearchName(name) {
|
function setSearchName(name) {
|
||||||
const p = this.buildQueryParams();
|
const p = buildQueryParams();
|
||||||
if (name !== p.name) {
|
if (name !== p.name) {
|
||||||
p.name = name;
|
p.name = name;
|
||||||
p.page = null;
|
p.page = null;
|
||||||
this.redirectToParams(p);
|
redirectToParams(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
setSearchTags(tags) {
|
function setSearchTags(tags) {
|
||||||
const p = this.buildQueryParams();
|
const p = buildQueryParams();
|
||||||
if (tags !== p.tags) {
|
if (tags !== p.tags) {
|
||||||
p.tags = tags;
|
p.tags = tags;
|
||||||
p.page = null;
|
p.page = null;
|
||||||
this.redirectToParams(p);
|
redirectToParams(p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
deleteRecipe(recipe) {
|
function deleteRecipe(recipe) {
|
||||||
this.recipeForDeletion = recipe;
|
recipeForDeletion.value = recipe;
|
||||||
},
|
}
|
||||||
|
|
||||||
recipeDeleteConfirm() {
|
function recipeDeleteConfirm() {
|
||||||
if (this.recipeForDeletion !== null) {
|
if (recipeForDeletion.value !== null) {
|
||||||
this.loadResource(
|
loadResource(
|
||||||
api.deleteRecipe(this.recipeForDeletion.id).then(() => {
|
api.deleteRecipe(recipeForDeletion.value.id).then(() => {
|
||||||
this.recipeForDeletion = null;
|
recipeForDeletion.value = null;
|
||||||
return this.getList();
|
return getList();
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
recipeDeleteCancel() {
|
function recipeDeleteCancel() {
|
||||||
this.recipeForDeletion = null;
|
recipeForDeletion.value = null;
|
||||||
},
|
}
|
||||||
|
|
||||||
getList() {
|
function formatRecipeTime(total, active) {
|
||||||
return this.loadResource(
|
|
||||||
api.getRecipeList(this.search.page, this.search.per, this.search.column, this.search.direction, this.search.name, this.search.tags, data => this.recipeData = data)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
formatRecipeTime(total, active) {
|
|
||||||
let str = "";
|
let str = "";
|
||||||
|
|
||||||
if (total && total > 0) {
|
if (total && total > 0) {
|
||||||
@ -295,24 +294,7 @@
|
|||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.$watch("search",
|
|
||||||
() => {
|
|
||||||
this.getList().then(() => this.initialLoad = true);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
deep: true,
|
|
||||||
immediate: true
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
AppLoading
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -19,12 +19,14 @@ require "rails/test_unit/railtie"
|
|||||||
# you've limited to :test, :development, or :production.
|
# you've limited to :test, :development, or :production.
|
||||||
Bundler.require(*Rails.groups)
|
Bundler.require(*Rails.groups)
|
||||||
|
|
||||||
|
require_relative '../lib/unit_conversion'
|
||||||
|
|
||||||
module Parsley
|
module Parsley
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
# Initialize configuration defaults for originally generated Rails version.
|
# Initialize configuration defaults for originally generated Rails version.
|
||||||
config.load_defaults 7.2
|
config.load_defaults 7.2
|
||||||
|
|
||||||
config.autoload_lib(ignore: %w(assets tasks unit_conversion))
|
config.autoload_lib(ignore: %w(assets tasks unit_conversion unit_conversion.rb))
|
||||||
|
|
||||||
config.action_dispatch.cookies_same_site_protection = :lax
|
config.action_dispatch.cookies_same_site_protection = :lax
|
||||||
config.active_record.collection_cache_versioning = true
|
config.active_record.collection_cache_versioning = true
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
require 'unit_conversion/constants'
|
require_relative './unit_conversion/constants'
|
||||||
require 'unit_conversion/errors'
|
require_relative './unit_conversion/errors'
|
||||||
require 'unit_conversion/formatters'
|
require_relative './unit_conversion/formatters'
|
||||||
require 'unit_conversion/parsed_number'
|
require_relative './unit_conversion/parsed_number'
|
||||||
require 'unit_conversion/parsed_unit'
|
require_relative './unit_conversion/parsed_unit'
|
||||||
require 'unit_conversion/conversions'
|
require_relative './unit_conversion/conversions'
|
||||||
require 'unit_conversion/unitwise_patch'
|
require_relative './unit_conversion/unitwise_patch'
|
||||||
require 'unit_conversion/value_unit'
|
require_relative './unit_conversion/value_unit'
|
||||||
|
|
||||||
module UnitConversion
|
module UnitConversion
|
||||||
class << self
|
class << self
|
||||||
|
@ -19,6 +19,9 @@ RSpec.describe Food, type: :model do
|
|||||||
|
|
||||||
i.density = '5 mile/hour'
|
i.density = '5 mile/hour'
|
||||||
expect(i).not_to be_valid
|
expect(i).not_to be_valid
|
||||||
|
|
||||||
|
i.density = '1 g/ml'
|
||||||
|
expect(i).to be_valid
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user