@@ -544,6 +601,10 @@ es:
color: var(--vn-text-color);
}
+.color-vn-text {
+ color: var(--vn-text-color);
+}
+
.q-table--dark .q-table__bottom,
.q-table--dark thead,
.q-table--dark tr,
diff --git a/src/components/VnTable/VnVisibleColumn.vue b/src/components/VnTable/VnVisibleColumn.vue
index 0f979acd3d..e3bb52637a 100644
--- a/src/components/VnTable/VnVisibleColumn.vue
+++ b/src/components/VnTable/VnVisibleColumn.vue
@@ -12,6 +12,10 @@ const $props = defineProps({
type: String,
default: '',
},
+ skip: {
+ type: Array,
+ default: () => [],
+ },
});
const { notify } = useNotify();
@@ -30,8 +34,12 @@ function setUserConfigViewData(data, isLocal) {
if (!data) return;
// Importante: El name de las columnas de la tabla debe conincidir con el name de las variables que devuelve la view config
if (!isLocal) localColumns.value = [];
+ // Array to Object
+ const skippeds = $props.skip.reduce((a, v) => ({ ...a, [v]: v }), {});
+
for (let column of columns.value) {
const { label, name } = column;
+ if (skippeds[name]) continue;
column.visible = data[name] ?? true;
if (!isLocal) localColumns.value.push({ name, label, visible: column.visible });
}
@@ -127,7 +135,7 @@ onMounted(async () => {
});
-
+
diff --git a/src/components/common/VnBreadcrumbs.vue b/src/components/common/VnBreadcrumbs.vue
index 3375072339..02226e4975 100644
--- a/src/components/common/VnBreadcrumbs.vue
+++ b/src/components/common/VnBreadcrumbs.vue
@@ -18,7 +18,7 @@ watchEffect(() => {
(matched) => Object.keys(matched.meta).length
);
breadcrumbs.value.length = 0;
-
+ if (!matched.value[0]) return;
if (matched.value[0].name != 'Dashboard') {
root.value = useCamelCase(matched.value[0].path.substring(1).toLowerCase());
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 3e5cd42163..e3bda6c8ef 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -75,6 +75,7 @@ const myOptions = ref([]);
const myOptionsOriginal = ref([]);
const vnSelectRef = ref();
const dataRef = ref();
+const lastVal = ref();
const value = computed({
get() {
@@ -85,14 +86,31 @@ const value = computed({
},
});
+watch(options, (newValue) => {
+ setOptions(newValue);
+});
+
+watch(modelValue, (newValue) => {
+ if (!myOptions.value.some((option) => option[optionValue.value] == newValue))
+ fetchFilter(newValue);
+});
+
+onMounted(() => {
+ setOptions(options.value);
+ if ($props.url && $props.modelValue && !findKeyInOptions())
+ fetchFilter($props.modelValue);
+ if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
+});
+
+function findKeyInOptions() {
+ if (!$props.options) return;
+ return filter($props.modelValue, $props.options)?.length;
+}
+
function setOptions(data) {
myOptions.value = JSON.parse(JSON.stringify(data));
myOptionsOriginal.value = JSON.parse(JSON.stringify(data));
}
-onMounted(() => {
- setOptions(options.value);
- if ($props.url && $props.modelValue) fetchFilter($props.modelValue);
-});
function filter(val, options) {
const search = val.toString().toLowerCase();
@@ -125,15 +143,21 @@ async function fetchFilter(val) {
const defaultWhere = $props.useLike
? { [key]: { like: `%${val}%` } }
: { [key]: val };
- const where = { ...defaultWhere, ...$props.where };
+ const where = { ...(val ? defaultWhere : {}), ...$props.where };
const fetchOptions = { where, order: sortBy, limit };
if (fields) fetchOptions.fields = fields;
return dataRef.value.fetch(fetchOptions);
}
async function filterHandler(val, update) {
- if (!$props.defaultFilter) return update();
+ if (!val && lastVal.value === val) {
+ lastVal.value = val;
+ return update();
+ }
+ lastVal.value = val;
let newOptions;
+
+ if (!$props.defaultFilter) return update();
if ($props.url) {
newOptions = await fetchFilter(val);
} else newOptions = filter(val, myOptionsOriginal.value);
@@ -149,19 +173,6 @@ async function filterHandler(val, update) {
}
);
}
-
-watch(options, (newValue) => {
- setOptions(newValue);
-});
-
-watch(modelValue, (newValue) => {
- if (!myOptions.value.some((option) => option[optionValue.value] == newValue))
- fetchFilter(newValue);
-});
-
-onMounted(async () => {
- if ($props.focusOnMount) setTimeout(() => vnSelectRef.value.showPopup(), 300);
-});
diff --git a/src/components/common/VnSelectCache.vue b/src/components/common/VnSelectCache.vue
new file mode 100644
index 0000000000..51873ef6ef
--- /dev/null
+++ b/src/components/common/VnSelectCache.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index 4981a163f1..7792ed2cd9 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -56,7 +56,12 @@ onBeforeMount(async () => {
skip: 0,
});
store = arrayData.store;
- entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
+ entity = computed(() => {
+ const data = (Array.isArray(store.data) ? store.data[0] : store.data) ?? {};
+ if (data) emit('onFetch', data);
+ return data;
+ });
+
// It enables to load data only once if the module is the same as the dataKey
if (!isSameDataKey.value || !route.params.id) await getData();
watch(
@@ -85,9 +90,9 @@ function getValueFromPath(path) {
const keys = path.toString().split('.');
let current = entity.value;
- for (let i = 0; i < keys.length; i++) {
- if (current[keys[i]] === undefined) return undefined;
- else current = current[keys[i]];
+ for (const key of keys) {
+ if (current[key] === undefined) return undefined;
+ else current = current[key];
}
return current;
}
diff --git a/src/components/ui/CatalogItem.vue b/src/components/ui/CatalogItem.vue
index 2b4724e35e..5c5d71018e 100644
--- a/src/components/ui/CatalogItem.vue
+++ b/src/components/ui/CatalogItem.vue
@@ -52,6 +52,10 @@ const dialog = ref(null);
:value="item?.[`value${index + 4}`]"
/>
+
+
+ {{ item.minQuantity }}
+