+
({ card: false, table: false }),
+ },
});
const { t } = useI18n();
const stateStore = useStateStore();
@@ -80,11 +88,13 @@ const tableModes = [
icon: 'view_column',
title: t('table view'),
value: TABLE_MODE,
+ disable: $props.disableOption?.table,
},
{
icon: 'grid_view',
title: t('grid view'),
value: DEFAULT_MODE,
+ disable: $props.disableOption?.card,
},
];
@@ -175,11 +185,14 @@ function columnName(col) {
}
function getColAlign(col) {
- return 'text-' + (col.align ?? 'left')
+ return 'text-' + (col.align ?? 'left');
}
+
+const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
defineExpose({
reload,
redirect: redirectFn,
+ selected,
});
@@ -225,11 +238,18 @@ defineExpose({
:search-url="searchUrl"
:disable-infinite-scroll="mode == TABLE_MODE"
@save-changes="reload"
- :has-subtoolbar="isEditable"
+ :has-sub-toolbar="$attrs['hasSubToolbar'] ?? isEditable"
>
+
+
+
rowClickFunction(row)"
+ @update:selected="emit('update:selected', $event)"
>
@@ -310,13 +331,15 @@ defineExpose({
class="no-margin q-px-xs"
:class="getColAlign(col)"
>
-
+
+
+
@@ -401,9 +424,9 @@ defineExpose({
>
@@ -412,14 +435,20 @@ defineExpose({
stopEventPropagation($event)
"
>
-
+ >
+
+
@@ -477,6 +506,7 @@ defineExpose({
default="input"
v-model="data[column.name]"
:show-label="true"
+ component-prop="columnCreate"
/>
diff --git a/src/components/common/VnCard.vue b/src/components/common/VnCard.vue
index 8517525df..c81bcd8e2 100644
--- a/src/components/common/VnCard.vue
+++ b/src/components/common/VnCard.vue
@@ -1,6 +1,6 @@
{},
},
value: {
- type: [Object, Number, String],
+ type: [Object, Number, String, Boolean],
default: () => {},
},
});
@@ -54,7 +54,6 @@ function toValueAttrs(attrs) {
v-bind="mix(toComponent).attrs"
v-on="mix(toComponent).event ?? {}"
v-model="model"
- class="fit"
/>
diff --git a/src/components/common/VnInput.vue b/src/components/common/VnInput.vue
index 4cd964012..33b97e29d 100644
--- a/src/components/common/VnInput.vue
+++ b/src/components/common/VnInput.vue
@@ -93,7 +93,12 @@ const inputRules = [
name="close"
size="xs"
v-if="hover && value && !$attrs.disabled && $props.clearable"
- @click="value = null"
+ @click="
+ () => {
+ value = null;
+ emit('remove');
+ }
+ "
>
diff --git a/src/components/common/VnInputDate.vue b/src/components/common/VnInputDate.vue
index 77ab2692d..184f8a158 100644
--- a/src/components/common/VnInputDate.vue
+++ b/src/components/common/VnInputDate.vue
@@ -1,84 +1,31 @@
-
-
-
-
-
+ v-if="
+ ($attrs.clearable == undefined || $attrs.clearable) &&
+ hover &&
+ model &&
+ !$attrs.disable
+ "
+ @click="
+ model = null;
+ isPopupOpen = false;
+ "
+ />
+
+
+ {
+ formattedDate = date;
+ isPopupOpen = false;
+ }
+ "
+ />
+
diff --git a/src/components/common/VnInputTime.vue b/src/components/common/VnInputTime.vue
index 5c84951cb..9344ff869 100644
--- a/src/components/common/VnInputTime.vue
+++ b/src/components/common/VnInputTime.vue
@@ -1,14 +1,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-es:
- Cancel: Cancelar
-
diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue
index 61436b7e8..19765b1f7 100644
--- a/src/components/common/VnLog.vue
+++ b/src/components/common/VnLog.vue
@@ -49,6 +49,7 @@ const filter = {
'changedModelId',
'changedModelValue',
'description',
+ 'summaryId',
],
include: [
{
@@ -459,12 +460,12 @@ onUnmounted(() => {
:style="{
backgroundColor: useColor(modelLog.model),
}"
- :title="modelLog.model"
+ :title="`${modelLog.model} #${modelLog.id}`"
>
{{ t(modelLog.modelI18n) }}
- #{{ modelLog.id }}#{{ modelLog.summaryId }}
{{ modelLog.showValue }}
diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue
index 52cb68438..3e5cd4216 100644
--- a/src/components/common/VnSelect.vue
+++ b/src/components/common/VnSelect.vue
@@ -61,6 +61,10 @@ const $props = defineProps({
type: Boolean,
default: false,
},
+ useLike: {
+ type: Boolean,
+ default: true,
+ },
});
const { t } = useI18n();
@@ -114,11 +118,14 @@ async function fetchFilter(val) {
if (!$props.url || !dataRef.value) return;
const { fields, sortBy, limit } = $props;
- let key = optionLabel.value;
+ let key = optionFilter.value ?? optionLabel.value;
- if (new RegExp(/\d/g).test(val)) key = optionFilter.value ?? optionValue.value;
+ if (new RegExp(/\d/g).test(val)) key = optionValue.value;
- const where = { ...{ [key]: { like: `%${val}%` } }, ...$props.where };
+ const defaultWhere = $props.useLike
+ ? { [key]: { like: `%${val}%` } }
+ : { [key]: val };
+ const where = { ...defaultWhere, ...$props.where };
const fetchOptions = { where, order: sortBy, limit };
if (fields) fetchOptions.fields = fields;
return dataRef.value.fetch(fetchOptions);
diff --git a/src/components/ui/CardDescriptor.vue b/src/components/ui/CardDescriptor.vue
index 8bb2a603e..2bb5234ad 100644
--- a/src/components/ui/CardDescriptor.vue
+++ b/src/components/ui/CardDescriptor.vue
@@ -46,7 +46,7 @@ let arrayData;
let store;
let entity;
const isLoading = ref(false);
-
+const isSameDataKey = computed(() => $props.dataKey === route.meta.moduleName);
defineExpose({ getData });
onBeforeMount(async () => {
@@ -58,10 +58,12 @@ onBeforeMount(async () => {
store = arrayData.store;
entity = computed(() => (Array.isArray(store.data) ? store.data[0] : store.data));
// It enables to load data only once if the module is the same as the dataKey
- if ($props.dataKey !== route.meta.moduleName || !route.params.id) await getData();
+ if (!isSameDataKey.value || !route.params.id) await getData();
watch(
() => [$props.url, $props.filter],
- async () => await getData()
+ async () => {
+ if (!isSameDataKey.value) await getData();
+ }
);
});
@@ -77,14 +79,50 @@ async function getData() {
isLoading.value = false;
}
}
+
+function getValueFromPath(path) {
+ if (!path) return;
+ 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]];
+ }
+ return current;
+}
+
const emit = defineEmits(['onFetch']);
+
+const iconModule = computed(() => route.matched[1].meta.icon);
+const toModule = computed(() =>
+ route.matched[1].path.split('/').length > 2
+ ? route.matched[1].redirect
+ : route.matched[1].children[0].redirect
+);