@katlux/preset-modern 0.1.1-alpha.91 → 0.1.1-alpha.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/runtime/components/KBulkActions/KBulkActions.d.vue.ts +3 -6
- package/dist/runtime/components/KBulkActions/KBulkActions.vue +20 -10
- package/dist/runtime/components/KBulkActions/KBulkActions.vue.d.ts +3 -6
- package/dist/runtime/components/KCheckbox/KCheckbox.vue +44 -2
- package/dist/runtime/components/KDatatable/KDatatable.d.vue.ts +20 -11
- package/dist/runtime/components/KDatatable/KDatatable.vue +83 -45
- package/dist/runtime/components/KDatatable/KDatatable.vue.d.ts +20 -11
- package/dist/runtime/components/KMaskTextbox/KMaskTextbox.d.vue.ts +4 -2
- package/dist/runtime/components/KMaskTextbox/KMaskTextbox.vue +10 -2
- package/dist/runtime/components/KMaskTextbox/KMaskTextbox.vue.d.ts +4 -2
- package/dist/runtime/components/KPagination/KPagination.vue +52 -44
- package/dist/runtime/components/KRadiobox/KRadiobox.vue +8 -2
- package/dist/runtime/components/KTextarea/KTextarea.d.vue.ts +2 -0
- package/dist/runtime/components/KTextarea/KTextarea.vue +54 -4
- package/dist/runtime/components/KTextarea/KTextarea.vue.d.ts +2 -0
- package/dist/runtime/components/KTextbox/KTextbox.vue +2 -2
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -4,16 +4,13 @@ type __VLS_Props = {
|
|
|
4
4
|
bulkActions: IKDatatableAction[];
|
|
5
5
|
selectedRows: any[];
|
|
6
6
|
selectAll: boolean;
|
|
7
|
+
selected?: any;
|
|
7
8
|
dp: CFlatClientDataProvider;
|
|
8
9
|
doAction: (action: any) => void;
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
'selected'?: any;
|
|
12
|
-
};
|
|
13
|
-
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
15
12
|
"update:selected": (value: any) => any;
|
|
16
|
-
}, string, import("vue").PublicProps, Readonly<
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
17
14
|
"onUpdate:selected"?: ((value: any) => any) | undefined;
|
|
18
15
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
16
|
declare const _default: typeof __VLS_export;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
template(v-if="bulkActions.length > 3")
|
|
6
6
|
KCombobox(
|
|
7
7
|
:dataProvider="dp"
|
|
8
|
-
v-model="
|
|
8
|
+
v-model="internalSelected"
|
|
9
9
|
labelField="label"
|
|
10
10
|
closeOnSelect
|
|
11
11
|
:disabled="selectedRows.length === 0"
|
|
@@ -13,41 +13,48 @@
|
|
|
13
13
|
class="action-select"
|
|
14
14
|
)
|
|
15
15
|
KButton(
|
|
16
|
-
@click="doAction(
|
|
16
|
+
@click="doAction(internalSelected)"
|
|
17
17
|
size="small"
|
|
18
|
-
:disabled="selectedRows.length === 0 ||
|
|
18
|
+
:disabled="selectedRows.length === 0 || internalSelected == undefined"
|
|
19
19
|
class="execute-btn"
|
|
20
20
|
) {{ t('Apply') }}
|
|
21
21
|
|
|
22
22
|
template(v-else v-for="action in bulkActions" :key="action.label")
|
|
23
23
|
KTooltip(
|
|
24
24
|
:text="action.label"
|
|
25
|
-
:disabled="!
|
|
25
|
+
:disabled="!action.iconOnly"
|
|
26
26
|
)
|
|
27
27
|
KButton(
|
|
28
28
|
@click="doAction(action)"
|
|
29
29
|
size="small"
|
|
30
30
|
:type="action.type || 'default'"
|
|
31
|
-
:iconOnly="action.iconOnly
|
|
31
|
+
:iconOnly="action.iconOnly"
|
|
32
|
+
:disabled="selectedRows.length === 0"
|
|
32
33
|
class="action-btn"
|
|
33
34
|
)
|
|
34
35
|
template(#icon v-if="action.icon")
|
|
35
36
|
KIcon(:iconname="action.icon" :width="16" :height="16")
|
|
36
|
-
template(#default v-if="!action.iconOnly
|
|
37
|
+
template(#default v-if="!action.iconOnly") {{ action.label }}
|
|
37
38
|
</template>
|
|
38
39
|
|
|
39
40
|
<script setup>
|
|
41
|
+
import { computed } from "vue";
|
|
40
42
|
import { CFlatClientDataProvider } from "@katlux/providers";
|
|
41
|
-
|
|
42
|
-
const t = (
|
|
43
|
-
const
|
|
44
|
-
defineProps({
|
|
43
|
+
import { useKatluxI18n } from "#toolkit/composables/useKatluxI18n";
|
|
44
|
+
const { t } = useKatluxI18n();
|
|
45
|
+
const props = defineProps({
|
|
45
46
|
bulkActions: { type: Array, required: true },
|
|
46
47
|
selectedRows: { type: Array, required: true },
|
|
47
48
|
selectAll: { type: Boolean, required: true },
|
|
49
|
+
selected: { type: null, required: false },
|
|
48
50
|
dp: { type: Object, required: true },
|
|
49
51
|
doAction: { type: Function, required: true }
|
|
50
52
|
});
|
|
53
|
+
const emit = defineEmits(["update:selected"]);
|
|
54
|
+
const internalSelected = computed({
|
|
55
|
+
get: () => props.selected,
|
|
56
|
+
set: (val) => emit("update:selected", val)
|
|
57
|
+
});
|
|
51
58
|
</script>
|
|
52
59
|
|
|
53
60
|
<style scoped>
|
|
@@ -60,6 +67,9 @@ defineProps({
|
|
|
60
67
|
gap: var(--gap-sm);
|
|
61
68
|
align-items: center;
|
|
62
69
|
}
|
|
70
|
+
.k-bulk-actions-modern .action-select {
|
|
71
|
+
min-width: 180px;
|
|
72
|
+
}
|
|
63
73
|
.k-bulk-actions-modern .action-btn {
|
|
64
74
|
border-radius: var(--border-radius-sm);
|
|
65
75
|
font-weight: var(--font-weight-medium);
|
|
@@ -4,16 +4,13 @@ type __VLS_Props = {
|
|
|
4
4
|
bulkActions: IKDatatableAction[];
|
|
5
5
|
selectedRows: any[];
|
|
6
6
|
selectAll: boolean;
|
|
7
|
+
selected?: any;
|
|
7
8
|
dp: CFlatClientDataProvider;
|
|
8
9
|
doAction: (action: any) => void;
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
-
'selected'?: any;
|
|
12
|
-
};
|
|
13
|
-
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
14
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
15
12
|
"update:selected": (value: any) => any;
|
|
16
|
-
}, string, import("vue").PublicProps, Readonly<
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
17
14
|
"onUpdate:selected"?: ((value: any) => any) | undefined;
|
|
18
15
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
16
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
.KCheckbox-wrapper
|
|
3
|
-
label.KCheckbox.modern-checkbox
|
|
4
|
-
|
|
3
|
+
label.KCheckbox.modern-checkbox(
|
|
4
|
+
role="checkbox"
|
|
5
|
+
:aria-checked="isChecked"
|
|
6
|
+
:aria-disabled="isDisabled"
|
|
7
|
+
tabindex="0"
|
|
8
|
+
@keydown.space.prevent="handleSpace"
|
|
9
|
+
)
|
|
10
|
+
input(type="checkbox" v-model="formattedModel" :value="checkboxValue" :disabled="isDisabled" tabindex="-1")
|
|
5
11
|
.checkbox-box(:class="validation ? `is-${validation}` : ''")
|
|
6
12
|
.checkbox-checkmark
|
|
7
13
|
KIcon.icon(iconname="check")
|
|
@@ -27,6 +33,42 @@ const formattedModel = computed({
|
|
|
27
33
|
get: () => props.model,
|
|
28
34
|
set: (value) => emit("update:model", value)
|
|
29
35
|
});
|
|
36
|
+
const findModelIndex = (arr, value) => {
|
|
37
|
+
const refIdx = arr.indexOf(value);
|
|
38
|
+
if (refIdx > -1) return refIdx;
|
|
39
|
+
if (value && typeof value === "object") {
|
|
40
|
+
const valId = value.id ?? value._id ?? value.key ?? value.value;
|
|
41
|
+
if (valId !== void 0 && valId !== null) {
|
|
42
|
+
return arr.findIndex((item) => {
|
|
43
|
+
if (!item || typeof item !== "object") return false;
|
|
44
|
+
const itemId = item.id ?? item._id ?? item.key ?? item.value;
|
|
45
|
+
return itemId === valId;
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return -1;
|
|
50
|
+
};
|
|
51
|
+
const isChecked = computed(() => {
|
|
52
|
+
if (Array.isArray(formattedModel.value)) {
|
|
53
|
+
return findModelIndex(formattedModel.value, props.checkboxValue) > -1;
|
|
54
|
+
}
|
|
55
|
+
return !!formattedModel.value;
|
|
56
|
+
});
|
|
57
|
+
const handleSpace = () => {
|
|
58
|
+
if (props.isDisabled) return;
|
|
59
|
+
if (Array.isArray(formattedModel.value)) {
|
|
60
|
+
const idx = findModelIndex(formattedModel.value, props.checkboxValue);
|
|
61
|
+
if (idx > -1) {
|
|
62
|
+
const updated = [...formattedModel.value];
|
|
63
|
+
updated.splice(idx, 1);
|
|
64
|
+
formattedModel.value = updated;
|
|
65
|
+
} else {
|
|
66
|
+
formattedModel.value = [...formattedModel.value, props.checkboxValue];
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
formattedModel.value = !formattedModel.value;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
30
72
|
</script>
|
|
31
73
|
|
|
32
74
|
<style scoped>
|
|
@@ -2,9 +2,11 @@ import { ADataProvider } from '@katlux/providers';
|
|
|
2
2
|
import type { IKDatatableAction } from '@katlux/providers';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
dataProvider: ADataProvider;
|
|
5
|
-
visibleFields
|
|
6
|
-
rowActions
|
|
7
|
-
bulkActions
|
|
5
|
+
visibleFields?: Array<string> | null;
|
|
6
|
+
rowActions?: Array<IKDatatableAction>;
|
|
7
|
+
bulkActions?: Array<IKDatatableAction>;
|
|
8
|
+
selectedRows?: any[];
|
|
9
|
+
selectAll?: boolean;
|
|
8
10
|
cellSlots?: Record<string, any>;
|
|
9
11
|
headerSlots?: Record<string, any>;
|
|
10
12
|
columnHeaders?: Record<string, string>;
|
|
@@ -12,17 +14,24 @@ type __VLS_Props = {
|
|
|
12
14
|
emptyStateText?: string;
|
|
13
15
|
emptyFilterStateText?: string;
|
|
14
16
|
};
|
|
15
|
-
|
|
16
|
-
'selectedRows'?: any[];
|
|
17
|
-
'selectAll'?: boolean;
|
|
18
|
-
};
|
|
19
|
-
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
20
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
17
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
21
18
|
"update:selectedRows": (value: any[]) => any;
|
|
22
19
|
"update:selectAll": (value: boolean) => any;
|
|
23
|
-
}, string, import("vue").PublicProps, Readonly<
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
24
21
|
"onUpdate:selectedRows"?: ((value: any[]) => any) | undefined;
|
|
25
22
|
"onUpdate:selectAll"?: ((value: boolean) => any) | undefined;
|
|
26
|
-
}>, {
|
|
23
|
+
}>, {
|
|
24
|
+
bulkActions: Array<IKDatatableAction>;
|
|
25
|
+
selectedRows: any[];
|
|
26
|
+
selectAll: boolean;
|
|
27
|
+
visibleFields: Array<string> | null;
|
|
28
|
+
rowActions: Array<IKDatatableAction>;
|
|
29
|
+
cellSlots: Record<string, any>;
|
|
30
|
+
headerSlots: Record<string, any>;
|
|
31
|
+
columnHeaders: Record<string, string>;
|
|
32
|
+
columnWidths: Record<string, string>;
|
|
33
|
+
emptyStateText: string;
|
|
34
|
+
emptyFilterStateText: string;
|
|
35
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
36
|
declare const _default: typeof __VLS_export;
|
|
28
37
|
export default _default;
|
|
@@ -1,74 +1,103 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.k-datatable.modern-datatable(:style="{ '--page-size':
|
|
3
|
-
.header(v-if="bulkActions && bulkActions.length > 0 && selectedRows.length > 0")
|
|
4
|
-
.selected-count {{ t('{count} items selected').replace('{count}', selectedRows
|
|
5
|
-
KBulkActions.bulk-actions(:bulkActions="bulkActions" :selectedRows="selectedRows" :selectAll="selectAll")
|
|
2
|
+
.k-datatable.modern-datatable(:style="{ '--page-size': dpPageSize || 10 }" role="region" :aria-label="t('Data Table')")
|
|
3
|
+
.header(v-if="props.bulkActions && props.bulkActions.length > 0 && selectedRows.length > 0")
|
|
4
|
+
.selected-count {{ t('{count} items selected').replace('{count}', (selectedRows?.length || 0).toString()) }}
|
|
5
|
+
KBulkActions.bulk-actions(:bulkActions="props.bulkActions" :selectedRows="selectedRows" :selectAll="selectAll")
|
|
6
6
|
|
|
7
7
|
.k-datatable-wrapper
|
|
8
|
-
.loading-overlay(v-if="
|
|
8
|
+
.loading-overlay(v-if="isLoading")
|
|
9
9
|
.spinner
|
|
10
10
|
|
|
11
|
-
table(role="grid" :aria-busy="
|
|
11
|
+
table(role="grid" :aria-busy="isLoading")
|
|
12
12
|
thead
|
|
13
13
|
tr
|
|
14
|
-
th.check-cell(v-if="bulkActions && bulkActions.length > 0")
|
|
14
|
+
th.check-cell(v-if="props.bulkActions && props.bulkActions.length > 0")
|
|
15
15
|
KCheckbox(v-model="selectAll")
|
|
16
|
-
th(v-for="field in visibleFields || dataProvider.fields" :key="field" :data-field="field" :style="getColumnStyle(field)")
|
|
16
|
+
th(v-for="field in visibleFields || props.dataProvider.fields" :key="field" :data-field="field" :style="getColumnStyle(field)")
|
|
17
17
|
component(v-if="getHeaderSlot(field)" :is="getHeaderSlot(field)" :field="field")
|
|
18
18
|
span(v-else) {{ columnHeaders?.[field] ?? field }}
|
|
19
|
-
th.actions-cell(v-if="rowActions && rowActions.length > 0") {{ t('Actions') }}
|
|
19
|
+
th.actions-cell(v-if="props.rowActions && props.rowActions.length > 0") {{ t('Actions') }}
|
|
20
20
|
|
|
21
21
|
tbody
|
|
22
|
-
tr.empty-row(v-if="!
|
|
23
|
-
td.empty-state(:colspan="(visibleFields || dataProvider.fields || []).length + (bulkActions && bulkActions.length > 0 ? 1 : 0) + (rowActions && rowActions.length > 0 ? 1 : 0)")
|
|
24
|
-
span(v-if="dataProvider.filter
|
|
25
|
-
span(v-else) {{ emptyStateText || t('No result') }}
|
|
26
|
-
tr(v-for="(row, index) in
|
|
27
|
-
td.check-cell(v-if="bulkActions && bulkActions.length > 0")
|
|
22
|
+
tr.empty-row(v-if="!isLoading && (!pageRows || pageRows.length === 0)")
|
|
23
|
+
td.empty-state(:colspan="(visibleFields || props.dataProvider.fields || []).length + (props.bulkActions && props.bulkActions.length > 0 ? 1 : 0) + (props.rowActions && props.rowActions.length > 0 ? 1 : 0)")
|
|
24
|
+
span(v-if="dpFilter?.active || props.dataProvider.filter?.value?.active") {{ props.emptyFilterStateText || t('No result found for filter') }}
|
|
25
|
+
span(v-else) {{ props.emptyStateText || t('No result') }}
|
|
26
|
+
tr(v-for="(row, index) in pageRows" :key="getRowKey(row, index)" :class="{ 'selected': isRowSelected(row) }")
|
|
27
|
+
td.check-cell(v-if="props.bulkActions && props.bulkActions.length > 0")
|
|
28
28
|
KCheckbox(:value="row" v-model="selectedRows")
|
|
29
|
-
td(v-for="visibleField in visibleFields || dataProvider.fields" :key="visibleField" :data-field="visibleField" :style="getColumnStyle(visibleField)")
|
|
29
|
+
td(v-for="visibleField in visibleFields || props.dataProvider.fields" :key="visibleField" :data-field="visibleField" :style="getColumnStyle(visibleField)")
|
|
30
30
|
component(v-if="getCellSlot(visibleField)" :is="getCellSlot(visibleField)" :row="row" :field="visibleField" :value="row[visibleField]")
|
|
31
31
|
span(v-else) {{ row[visibleField] }}
|
|
32
|
-
td.actions-cell(v-if="rowActions && rowActions.length > 0")
|
|
32
|
+
td.actions-cell(v-if="props.rowActions && props.rowActions.length > 0")
|
|
33
33
|
.action-buttons
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
KButton.action-btn(
|
|
41
|
-
:type="rowAction.type || 'default'"
|
|
42
|
-
:iconOnly="rowAction.iconOnly || !!rowAction.icon"
|
|
43
|
-
size="small"
|
|
44
|
-
@click="rowAction.action(row)"
|
|
34
|
+
template(v-for="rowAction in props.rowActions" :key="rowAction.label")
|
|
35
|
+
KTooltip(
|
|
36
|
+
v-if="!rowAction.visible || rowAction.visible(row)"
|
|
37
|
+
:text="rowAction.label"
|
|
38
|
+
:disabled="!rowAction.iconOnly"
|
|
45
39
|
)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
40
|
+
KButton.action-btn(
|
|
41
|
+
:type="rowAction.type || 'default'"
|
|
42
|
+
:iconOnly="rowAction.iconOnly"
|
|
43
|
+
size="small"
|
|
44
|
+
@click="rowAction.action(row)"
|
|
45
|
+
)
|
|
46
|
+
template(#icon v-if="rowAction.icon")
|
|
47
|
+
KIcon(:iconname="rowAction.icon" :width="16" :height="16")
|
|
48
|
+
template(#default v-if="!rowAction.iconOnly") {{ rowAction.label }}
|
|
49
49
|
|
|
50
50
|
.footer
|
|
51
|
-
KPagination.pagination(:dataProvider="dataProvider")
|
|
51
|
+
KPagination.pagination(:dataProvider="props.dataProvider")
|
|
52
52
|
</template>
|
|
53
53
|
|
|
54
54
|
<script setup>
|
|
55
|
+
import { computed } from "vue";
|
|
55
56
|
import { ADataProvider } from "@katlux/providers";
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
const selectAll = defineModel("selectAll", { type: Boolean, ...{ default: false } });
|
|
57
|
+
import { useKatluxI18n } from "#toolkit/composables/useKatluxI18n";
|
|
58
|
+
import { useDataProvider } from "#toolkit/composables/useDataProvider";
|
|
59
|
+
const { t } = useKatluxI18n();
|
|
60
60
|
const props = defineProps({
|
|
61
61
|
dataProvider: { type: Object, required: true },
|
|
62
|
-
visibleFields: { type: [Array, null], required:
|
|
63
|
-
rowActions: { type: Array, required:
|
|
64
|
-
bulkActions: { type: Array, required:
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
62
|
+
visibleFields: { type: [Array, null], required: false, default: null },
|
|
63
|
+
rowActions: { type: Array, required: false, default: () => [] },
|
|
64
|
+
bulkActions: { type: Array, required: false, default: () => [] },
|
|
65
|
+
selectedRows: { type: Array, required: false, default: () => [] },
|
|
66
|
+
selectAll: { type: Boolean, required: false, default: false },
|
|
67
|
+
cellSlots: { type: Object, required: false, default: void 0 },
|
|
68
|
+
headerSlots: { type: Object, required: false, default: void 0 },
|
|
69
|
+
columnHeaders: { type: Object, required: false, default: void 0 },
|
|
70
|
+
columnWidths: { type: Object, required: false, default: void 0 },
|
|
71
|
+
emptyStateText: { type: String, required: false, default: "" },
|
|
72
|
+
emptyFilterStateText: { type: String, required: false, default: "" }
|
|
71
73
|
});
|
|
74
|
+
const emit = defineEmits(["update:selectedRows", "update:selectAll"]);
|
|
75
|
+
const selectedRows = computed({
|
|
76
|
+
get: () => props.selectedRows || [],
|
|
77
|
+
set: (val) => emit("update:selectedRows", val)
|
|
78
|
+
});
|
|
79
|
+
const selectAll = computed({
|
|
80
|
+
get: () => props.selectAll || false,
|
|
81
|
+
set: (val) => emit("update:selectAll", val)
|
|
82
|
+
});
|
|
83
|
+
const getRowKey = (row, index) => {
|
|
84
|
+
const idKey = props.dataProvider?.idKey || "id";
|
|
85
|
+
if (row && row[idKey] !== void 0 && row[idKey] !== null) {
|
|
86
|
+
return row[idKey];
|
|
87
|
+
}
|
|
88
|
+
if (row && row.id !== void 0 && row.id !== null) {
|
|
89
|
+
return row.id;
|
|
90
|
+
}
|
|
91
|
+
if (row && row._id !== void 0 && row._id !== null) {
|
|
92
|
+
return row._id;
|
|
93
|
+
}
|
|
94
|
+
return index;
|
|
95
|
+
};
|
|
96
|
+
const isRowSelected = (row) => {
|
|
97
|
+
const idKey = props.dataProvider?.idKey || "id";
|
|
98
|
+
const rowId = row?.[idKey] ?? row?.id ?? row?._id ?? row;
|
|
99
|
+
return (selectedRows.value || []).some((r) => (r?.[idKey] ?? r?.id ?? r?._id ?? r) === rowId || r === row);
|
|
100
|
+
};
|
|
72
101
|
const getCellSlot = (fieldName) => {
|
|
73
102
|
const slotName = "cell-" + fieldName;
|
|
74
103
|
return props.cellSlots?.[slotName];
|
|
@@ -82,6 +111,11 @@ const getColumnStyle = (field) => {
|
|
|
82
111
|
if (!w) return void 0;
|
|
83
112
|
return { width: w, whiteSpace: "nowrap" };
|
|
84
113
|
};
|
|
114
|
+
const { pageData, filter: dpFilter, loading: dpLoading, initialLoad: dpInitialLoad, pageSize: dpPageSize } = useDataProvider(props.dataProvider);
|
|
115
|
+
const pageRows = computed(() => pageData.value || []);
|
|
116
|
+
const isLoading = computed(() => {
|
|
117
|
+
return dpLoading.value || dpInitialLoad.value || false;
|
|
118
|
+
});
|
|
85
119
|
</script>
|
|
86
120
|
|
|
87
121
|
<style scoped>
|
|
@@ -151,6 +185,8 @@ const getColumnStyle = (field) => {
|
|
|
151
185
|
text-align: center;
|
|
152
186
|
}
|
|
153
187
|
.modern-datatable table thead th.actions-cell {
|
|
188
|
+
width: 1%;
|
|
189
|
+
white-space: nowrap;
|
|
154
190
|
text-align: right;
|
|
155
191
|
}
|
|
156
192
|
.modern-datatable table tbody tr {
|
|
@@ -166,6 +202,8 @@ const getColumnStyle = (field) => {
|
|
|
166
202
|
text-align: center;
|
|
167
203
|
}
|
|
168
204
|
.modern-datatable table tbody tr td.actions-cell {
|
|
205
|
+
width: 1%;
|
|
206
|
+
white-space: nowrap;
|
|
169
207
|
text-align: right;
|
|
170
208
|
}
|
|
171
209
|
.modern-datatable table tbody tr td.empty-state {
|
|
@@ -2,9 +2,11 @@ import { ADataProvider } from '@katlux/providers';
|
|
|
2
2
|
import type { IKDatatableAction } from '@katlux/providers';
|
|
3
3
|
type __VLS_Props = {
|
|
4
4
|
dataProvider: ADataProvider;
|
|
5
|
-
visibleFields
|
|
6
|
-
rowActions
|
|
7
|
-
bulkActions
|
|
5
|
+
visibleFields?: Array<string> | null;
|
|
6
|
+
rowActions?: Array<IKDatatableAction>;
|
|
7
|
+
bulkActions?: Array<IKDatatableAction>;
|
|
8
|
+
selectedRows?: any[];
|
|
9
|
+
selectAll?: boolean;
|
|
8
10
|
cellSlots?: Record<string, any>;
|
|
9
11
|
headerSlots?: Record<string, any>;
|
|
10
12
|
columnHeaders?: Record<string, string>;
|
|
@@ -12,17 +14,24 @@ type __VLS_Props = {
|
|
|
12
14
|
emptyStateText?: string;
|
|
13
15
|
emptyFilterStateText?: string;
|
|
14
16
|
};
|
|
15
|
-
|
|
16
|
-
'selectedRows'?: any[];
|
|
17
|
-
'selectAll'?: boolean;
|
|
18
|
-
};
|
|
19
|
-
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
20
|
-
declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
17
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
21
18
|
"update:selectedRows": (value: any[]) => any;
|
|
22
19
|
"update:selectAll": (value: boolean) => any;
|
|
23
|
-
}, string, import("vue").PublicProps, Readonly<
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
24
21
|
"onUpdate:selectedRows"?: ((value: any[]) => any) | undefined;
|
|
25
22
|
"onUpdate:selectAll"?: ((value: boolean) => any) | undefined;
|
|
26
|
-
}>, {
|
|
23
|
+
}>, {
|
|
24
|
+
bulkActions: Array<IKDatatableAction>;
|
|
25
|
+
selectedRows: any[];
|
|
26
|
+
selectAll: boolean;
|
|
27
|
+
visibleFields: Array<string> | null;
|
|
28
|
+
rowActions: Array<IKDatatableAction>;
|
|
29
|
+
cellSlots: Record<string, any>;
|
|
30
|
+
headerSlots: Record<string, any>;
|
|
31
|
+
columnHeaders: Record<string, string>;
|
|
32
|
+
columnWidths: Record<string, string>;
|
|
33
|
+
emptyStateText: string;
|
|
34
|
+
emptyFilterStateText: string;
|
|
35
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
36
|
declare const _default: typeof __VLS_export;
|
|
28
37
|
export default _default;
|
|
@@ -4,13 +4,15 @@ type __VLS_Props = {
|
|
|
4
4
|
placeholder: string;
|
|
5
5
|
showClear: boolean;
|
|
6
6
|
mask: string;
|
|
7
|
+
validation?: 'success' | 'warning' | 'error' | null;
|
|
8
|
+
validationText?: string;
|
|
7
9
|
};
|
|
8
10
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
-
"update:maskedValue": (value: string) => any;
|
|
10
11
|
clear: () => any;
|
|
12
|
+
"update:maskedValue": (value: string) => any;
|
|
11
13
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
-
"onUpdate:maskedValue"?: ((value: string) => any) | undefined;
|
|
13
14
|
onClear?: (() => any) | undefined;
|
|
15
|
+
"onUpdate:maskedValue"?: ((value: string) => any) | undefined;
|
|
14
16
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
17
|
declare const _default: typeof __VLS_export;
|
|
16
18
|
export default _default;
|
|
@@ -5,7 +5,10 @@
|
|
|
5
5
|
:modelValue="maskedValue"
|
|
6
6
|
:placeholder="placeholder"
|
|
7
7
|
:showClear="showClear"
|
|
8
|
+
:clear="handleClear"
|
|
8
9
|
:maxlength="mask.length"
|
|
10
|
+
:validation="validation"
|
|
11
|
+
:validationText="validationText"
|
|
9
12
|
@update:modelValue="handleUpdate"
|
|
10
13
|
@beforeinput="handleBeforeInput"
|
|
11
14
|
)
|
|
@@ -13,13 +16,15 @@
|
|
|
13
16
|
|
|
14
17
|
<script setup>
|
|
15
18
|
import { computed } from "vue";
|
|
16
|
-
import { getMaskPatternDef } from "
|
|
19
|
+
import { getMaskPatternDef } from "#toolkit/components/KMaskTextbox/KMaskTextbox.logic";
|
|
17
20
|
const props = defineProps({
|
|
18
21
|
label: { type: String, required: false },
|
|
19
22
|
maskedValue: { type: String, required: true },
|
|
20
23
|
placeholder: { type: String, required: true },
|
|
21
24
|
showClear: { type: Boolean, required: true },
|
|
22
|
-
mask: { type: String, required: true }
|
|
25
|
+
mask: { type: String, required: true },
|
|
26
|
+
validation: { type: [String, null], required: false },
|
|
27
|
+
validationText: { type: String, required: false }
|
|
23
28
|
});
|
|
24
29
|
const emit = defineEmits(["update:maskedValue", "clear"]);
|
|
25
30
|
const handleBeforeInput = (event) => {
|
|
@@ -97,6 +102,9 @@ const handleBeforeInput = (event) => {
|
|
|
97
102
|
const handleUpdate = (value) => {
|
|
98
103
|
emit("update:maskedValue", value);
|
|
99
104
|
};
|
|
105
|
+
const handleClear = () => {
|
|
106
|
+
emit("clear");
|
|
107
|
+
};
|
|
100
108
|
</script>
|
|
101
109
|
|
|
102
110
|
<style lang="scss" scoped>
|
|
@@ -4,13 +4,15 @@ type __VLS_Props = {
|
|
|
4
4
|
placeholder: string;
|
|
5
5
|
showClear: boolean;
|
|
6
6
|
mask: string;
|
|
7
|
+
validation?: 'success' | 'warning' | 'error' | null;
|
|
8
|
+
validationText?: string;
|
|
7
9
|
};
|
|
8
10
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
9
|
-
"update:maskedValue": (value: string) => any;
|
|
10
11
|
clear: () => any;
|
|
12
|
+
"update:maskedValue": (value: string) => any;
|
|
11
13
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
-
"onUpdate:maskedValue"?: ((value: string) => any) | undefined;
|
|
13
14
|
onClear?: (() => any) | undefined;
|
|
15
|
+
"onUpdate:maskedValue"?: ((value: string) => any) | undefined;
|
|
14
16
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
15
17
|
declare const _default: typeof __VLS_export;
|
|
16
18
|
export default _default;
|
|
@@ -1,56 +1,64 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.k-pagination-modern(v-if="totalPages > 1")
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
nav.k-pagination-modern(v-if="totalPages > 1" :aria-label="t('Pagination Navigation')")
|
|
3
|
+
ul.pagination-list
|
|
4
|
+
li(v-if="showPrevButton")
|
|
5
|
+
KButton.nav-btn(
|
|
6
|
+
@click="goToPrev"
|
|
7
|
+
:disabled="!showPrevButton"
|
|
8
|
+
:href="getPageHref(dp.currentPage.value - 1)"
|
|
9
|
+
size="small"
|
|
10
|
+
type="light"
|
|
11
|
+
:aria-label="t('Previous Page')"
|
|
12
|
+
) ‹
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
li(v-if="showFirstEllipsis")
|
|
15
|
+
KButton.page-btn(
|
|
16
|
+
@click="goToFirst"
|
|
17
|
+
:href="getPageHref(1)"
|
|
18
|
+
size="small"
|
|
19
|
+
type="light"
|
|
20
|
+
:aria-label="t('Go to Page 1')"
|
|
21
|
+
) 1
|
|
22
|
+
|
|
23
|
+
li(v-if="showFirstEllipsis")
|
|
24
|
+
span.ellipsis ...
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
li(v-for="item in visiblePages" :key="item")
|
|
27
|
+
KButton.page-btn(
|
|
28
|
+
@click="() => pageClicked(item)"
|
|
29
|
+
:href="getPageHref(item)"
|
|
30
|
+
size="small"
|
|
31
|
+
:type="item === dp.currentPage.value ? 'primary' : 'light'"
|
|
32
|
+
:aria-current="item === dp.currentPage.value ? 'page' : undefined"
|
|
33
|
+
:aria-label="t('Page') + ' ' + item"
|
|
34
|
+
) {{ item }}
|
|
30
35
|
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
li(v-if="showLastEllipsis")
|
|
37
|
+
span.ellipsis ...
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
li(v-if="showLastEllipsis")
|
|
40
|
+
KButton.page-btn(
|
|
41
|
+
@click="goToLast"
|
|
42
|
+
:href="getPageHref(totalPages)"
|
|
43
|
+
size="small"
|
|
44
|
+
type="light"
|
|
45
|
+
:aria-label="t('Go to Page') + ' ' + totalPages"
|
|
46
|
+
) {{ totalPages }}
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
li(v-if="showNextButton")
|
|
49
|
+
KButton.nav-btn(
|
|
50
|
+
@click="goToNext"
|
|
51
|
+
:disabled="!showNextButton"
|
|
52
|
+
:href="getPageHref(dp.currentPage.value + 1)"
|
|
53
|
+
size="small"
|
|
54
|
+
type="light"
|
|
55
|
+
:aria-label="t('Next Page')"
|
|
56
|
+
) ›
|
|
49
57
|
</template>
|
|
50
58
|
|
|
51
59
|
<script setup>
|
|
52
|
-
|
|
53
|
-
const t = (
|
|
60
|
+
import { useKatluxI18n } from "#toolkit/composables/useKatluxI18n";
|
|
61
|
+
const { t } = useKatluxI18n();
|
|
54
62
|
defineProps({
|
|
55
63
|
dp: { type: null, required: true },
|
|
56
64
|
totalPages: { type: Number, required: true },
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
2
|
.KRadiobox-wrapper
|
|
3
|
-
label.KRadiobox.modern-radiobox
|
|
4
|
-
|
|
3
|
+
label.KRadiobox.modern-radiobox(
|
|
4
|
+
role="radio"
|
|
5
|
+
:aria-checked="internalModel === value"
|
|
6
|
+
:aria-disabled="disabled"
|
|
7
|
+
tabindex="0"
|
|
8
|
+
@keydown.space.prevent="internalModel = value"
|
|
9
|
+
)
|
|
10
|
+
input(type="radio" v-model="internalModel" :value="value" :disabled="disabled" tabindex="-1")
|
|
5
11
|
.radiobox-box(:class="validation ? `is-${validation}` : ''")
|
|
6
12
|
.radiobox-checkmark
|
|
7
13
|
KIcon.icon(iconname="check")
|
|
@@ -1,15 +1,33 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
.KTextarea-wrapper
|
|
2
|
+
.KTextarea-wrapper(:class="$attrs.class" :style="$attrs.style")
|
|
3
3
|
label.k-input-label(v-if="label") {{ label }}
|
|
4
|
-
textarea.KTextarea.modern-textarea(
|
|
4
|
+
textarea.KTextarea.modern-textarea(
|
|
5
|
+
v-bind="textareaAttrs"
|
|
6
|
+
v-model="text"
|
|
7
|
+
:placeholder="placeholder"
|
|
8
|
+
:rows="rows"
|
|
9
|
+
:class="validation ? `is-${validation}` : ''"
|
|
10
|
+
)
|
|
11
|
+
span.validation-text(v-if="validation && ['success', 'warning', 'error'].includes(validation) && validationText" :class="`is-${validation}`") {{ validationText }}
|
|
5
12
|
</template>
|
|
6
13
|
|
|
7
14
|
<script setup>
|
|
15
|
+
import { useAttrs, computed } from "vue";
|
|
16
|
+
defineOptions({
|
|
17
|
+
inheritAttrs: false
|
|
18
|
+
});
|
|
8
19
|
const text = defineModel("text", { type: String });
|
|
9
|
-
defineProps({
|
|
20
|
+
const props = defineProps({
|
|
10
21
|
placeholder: { type: String, required: true },
|
|
11
22
|
rows: { type: Number, required: true },
|
|
12
|
-
label: { type: String, required: false }
|
|
23
|
+
label: { type: String, required: false },
|
|
24
|
+
validation: { type: [String, null], required: false },
|
|
25
|
+
validationText: { type: String, required: false }
|
|
26
|
+
});
|
|
27
|
+
const attrs = useAttrs();
|
|
28
|
+
const textareaAttrs = computed(() => {
|
|
29
|
+
const { class: _, style: __, ...rest } = attrs;
|
|
30
|
+
return rest;
|
|
13
31
|
});
|
|
14
32
|
</script>
|
|
15
33
|
|
|
@@ -52,4 +70,36 @@ defineProps({
|
|
|
52
70
|
color: var(--neutral-400);
|
|
53
71
|
cursor: not-allowed;
|
|
54
72
|
}
|
|
73
|
+
.KTextarea.modern-textarea.is-error {
|
|
74
|
+
border-color: var(--color-danger, #ef4444);
|
|
75
|
+
}
|
|
76
|
+
.KTextarea.modern-textarea.is-error:focus {
|
|
77
|
+
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.2);
|
|
78
|
+
}
|
|
79
|
+
.KTextarea.modern-textarea.is-warning {
|
|
80
|
+
border-color: var(--color-warning, #f59e0b);
|
|
81
|
+
}
|
|
82
|
+
.KTextarea.modern-textarea.is-warning:focus {
|
|
83
|
+
box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.2);
|
|
84
|
+
}
|
|
85
|
+
.KTextarea.modern-textarea.is-success {
|
|
86
|
+
border-color: var(--color-success, #10b981);
|
|
87
|
+
}
|
|
88
|
+
.KTextarea.modern-textarea.is-success:focus {
|
|
89
|
+
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.2);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.validation-text {
|
|
93
|
+
font-size: var(--font-size-xs, 12px);
|
|
94
|
+
margin-top: 4px;
|
|
95
|
+
}
|
|
96
|
+
.validation-text.is-error {
|
|
97
|
+
color: var(--color-danger, #ef4444);
|
|
98
|
+
}
|
|
99
|
+
.validation-text.is-warning {
|
|
100
|
+
color: var(--color-warning, #f59e0b);
|
|
101
|
+
}
|
|
102
|
+
.validation-text.is-success {
|
|
103
|
+
color: var(--color-success, #10b981);
|
|
104
|
+
}
|
|
55
105
|
</style>
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
<script setup>
|
|
12
12
|
import { computed, useAttrs } from "vue";
|
|
13
|
-
|
|
14
|
-
const t = (
|
|
13
|
+
import { useKatluxI18n } from "#toolkit/composables/useKatluxI18n";
|
|
14
|
+
const { t } = useKatluxI18n();
|
|
15
15
|
defineOptions({
|
|
16
16
|
inheritAttrs: false
|
|
17
17
|
});
|
package/package.json
CHANGED