lkt-table 1.1.2 → 1.2.0

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/style.css CHANGED
@@ -1 +1 @@
1
- .lkt-table{width:var(--table-width);overflow-x:auto;font-family:var(--table-font-family)}.lkt-table>table{width:100%;max-width:100%;border-collapse:separate;border-radius:var(--table-border-radius);border-spacing:0}.lkt-table th,.lkt-table td{vertical-align:middle;text-align:var(--table-text-align);padding:var(--table-row-padding);font-size:var(--table-row-font-size);color:var(--table-row-color)}.lkt-table th{font-family:var(--table-header-font-family);padding:var(--table-header-padding)}.lkt-table thead tr{background-color:var(--table-header-background)}.lkt-table tbody tr{background-color:var(--table-row-background)}.lkt-table tbody tr:nth-child(odd){background-color:var(--table-row-background-odd)}.lkt-table [data-sort=asc]>div,.lkt-table [data-sort=desc]>div{display:inline-block}.lkt-table [data-sort=asc]>div:after,.lkt-table [data-sort=desc]>div:after{font-family:var(--table-sort-icon-font-family);display:inline-block;font-size:var(--table-sort-icon-font-size)}.lkt-table [data-sort=asc]>div:after{content:var(--table-sort-asc-icon-content)}.lkt-table [data-sort=desc]>div:after{content:var(--table-sort-desc-icon-content)}.lkt-table td[data-role=drag-indicator],.lkt-table td[data-role=invalid-drag-indicator]{width:var(--table-drag-indicator-width);height:40px;padding:0!important;position:relative;background:#eee;cursor:pointer}.lkt-table td[data-role=drag-indicator]:before,.lkt-table td[data-role=invalid-drag-indicator]:before{content:"";display:block;background:#eee;width:18px;height:36px;margin:auto}.lkt-table td[data-role=drag-indicator]:after,.lkt-table td[data-role=invalid-drag-indicator]:after{content:"…";color:#000;display:block;position:absolute;top:50%;left:50%;font-weight:700;width:15px;height:7px;transform:rotate(90deg);transform-origin:center center}[data-lkt=empty-table]{border:1px solid #ddd;border-radius:var(--table-border-radius);width:100%;padding:10px;background-color:#f8f7e5;font-family:var(--table-font-family);font-size:13px;color:#444;text-align:var(--table-text-align)}.sortable-chosen{border:var(--table-sortable-chosen-border)}.sortable-chosen.ghost{background:var(--table-sortable-chosen-ghost-background)}
1
+ .lkt-table-page,.lkt-table-page-content-wrapper{display:flex;width:100%;flex-direction:column;gap:var(--lkt-table-page-gap)}.lkt-table{width:var(--lkt-table-width);overflow-x:auto;font-family:var(--lkt-table-font-family),serif}.lkt-table>table{width:100%;max-width:100%;border-collapse:separate;border-radius:var(--lkt-table-border-radius);border-spacing:0}.lkt-table th,.lkt-table td{vertical-align:middle;text-align:var(--lkt-table-text-align);padding:var(--lkt-table-padding-row);font-size:var(--lkt-table-font-size-row);color:var(--lkt-table-color-row)}.lkt-table th{font-family:var(--lkt-table-font-family-header),serif;padding:var(--lkt-table-padding-header)}.lkt-table thead tr{background-color:var(--lkt-table-bg-header)}.lkt-table tbody tr{background-color:var(--lkt-table-bg-row)}.lkt-table tbody tr:nth-child(odd){background-color:var(--lkt-table-bg-row-odd)}.lkt-table [data-sort=asc]>div,.lkt-table [data-sort=desc]>div{display:inline-block}.lkt-table [data-sort=asc]>div:after,.lkt-table [data-sort=desc]>div:after{font-family:var(--lkt-table-font-family-sort-icon),serif;display:inline-block;font-size:var(--lkt-table-font-size-sort-icon)}.lkt-table [data-sort=asc]>div:after{content:var(--lkt-table-sort-icon-content-asc)}.lkt-table [data-sort=desc]>div:after{content:var(--lkt-table-sort-icon-content-desc)}.lkt-table td[data-role=drag-indicator],.lkt-table td[data-role=invalid-drag-indicator]{width:var(--lkt-table-width-drag);height:40px;padding:0!important;position:relative;background:#eee;cursor:pointer}.lkt-table td[data-role=drag-indicator]:before,.lkt-table td[data-role=invalid-drag-indicator]:before{content:"";display:block;background:#eee;width:18px;height:36px;margin:auto}.lkt-table td[data-role=drag-indicator]:after,.lkt-table td[data-role=invalid-drag-indicator]:after{content:"…";color:#000;display:block;position:absolute;top:50%;left:50%;font-weight:700;width:15px;height:7px;transform:rotate(90deg);transform-origin:center center}[data-lkt=empty-table]{border:1px solid #ddd;border-radius:var(--lkt-table-border-radius);width:100%;padding:10px;background-color:#f8f7e5;font-family:var(--lkt-table-font-family);font-size:13px;color:#444;text-align:var(--lkt-table-text-align)}.sortable-chosen{border:var(--lkt-table-border-sortable-chosen)}.sortable-chosen.ghost{background:var(--lkt-table-bg-sortable-chosen-ghost)}.lkt-table td.lkt-table-nav-cell{padding:0}.lkt-table-nav-container{display:flex;align-items:center;flex-direction:column;justify-content:center}.lkt-table-page-buttons{position:sticky;top:calc(-1 * var(--lkt-table-gap-buttons));display:flex;align-items:center;gap:var(--lkt-table-gap-buttons);transition:all linear .15s;background:transparent;z-index:2}.lkt-table-page-buttons-bottom{justify-content:center}.lkt-table-page-buttons>.switch-edition-mode{margin-left:auto}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lkt-table",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "keywords": [
6
6
  "lkt",
@@ -16,12 +16,15 @@
16
16
  ".": {
17
17
  "import": "./dist/build.js"
18
18
  },
19
- "./styles": "./dist/style.css"
19
+ "./styles": "./dist/style.css",
20
+ "./theme": "./theme/default.css",
21
+ "./theme/default": "./theme/default.css"
20
22
  },
21
23
  "types": "./dist/index.d.ts",
22
24
  "files": [
23
25
  "dist/*",
24
- "src/**/*.vue"
26
+ "src/**/*.vue",
27
+ "theme/**/*.css"
25
28
  ],
26
29
  "license": "MIT",
27
30
  "sideEffects": false,
@@ -43,17 +46,22 @@
43
46
  "node": ">=18"
44
47
  },
45
48
  "dependencies": {
49
+ "lkt-button": "^1.1.16",
50
+ "lkt-data-state": "^1.0.10",
46
51
  "lkt-events": "^1.0.4",
47
- "lkt-field-check": "^1.0.0",
52
+ "lkt-field-file": "^1.1.1",
48
53
  "lkt-field-select": "^1.0.0",
49
54
  "lkt-field-switch": "^1.0.0",
50
55
  "lkt-field-text": "^1.0.0",
56
+ "lkt-field-textarea": "^1.1.3",
51
57
  "lkt-http-client": "^1.0.19",
58
+ "lkt-i18n": "^1.0.4",
52
59
  "lkt-loader": "^1.0.2",
60
+ "lkt-paginator": "^1.1.4",
53
61
  "lkt-string-tools": "^1.0.3",
54
62
  "lkt-ts-interfaces": "^1.0.2",
63
+ "sortablejs": "^1.15.2",
55
64
  "vue": "^3.3",
56
- "vue-router": "^4.2.5",
57
- "vuedraggable": "^4.1.0"
65
+ "vue-router": "^4.2.5"
58
66
  }
59
67
  }
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import {computed} from "vue";
3
+ import {Settings} from "../settings/Settings";
4
+ import {__} from "lkt-i18n";
5
+
6
+ const emit = defineEmits(['click']);
7
+
8
+ const props = withDefaults(defineProps<{
9
+ disabled: boolean
10
+ text: boolean
11
+ }>(), {
12
+ disabled: false,
13
+ text: '',
14
+ });
15
+
16
+ const hasCreateButtonSlot = computed(() => {
17
+ return Settings.createButtonSlot !== '';
18
+ }),
19
+ createButtonSlot = computed(() => {
20
+ return Settings.createButtonSlot;
21
+ }),
22
+ computedText = computed(() => {
23
+ if (props.text.startsWith('__:')) {
24
+ return __(props.text.substring(3));
25
+ }
26
+ return props.text;
27
+ })
28
+ </script>
29
+
30
+ <template>
31
+ <lkt-button
32
+ palette="table-create"
33
+ :disabled="disabled"
34
+ @click="emit('click')">
35
+ <template v-if="hasCreateButtonSlot">
36
+ <component
37
+ :is="createButtonSlot"/>
38
+ </template>
39
+ <template v-else>
40
+ <i class=""/> {{computedText}}
41
+ </template>
42
+ </lkt-button>
43
+ </template>
@@ -0,0 +1,43 @@
1
+ <script setup lang="ts">
2
+ import {computed} from "vue";
3
+ import {Settings} from "../settings/Settings";
4
+ import {__} from "lkt-i18n";
5
+
6
+ const emit = defineEmits(['click']);
7
+
8
+ const props = withDefaults(defineProps<{
9
+ disabled: boolean
10
+ text: boolean
11
+ }>(), {
12
+ disabled: false,
13
+ text: '',
14
+ });
15
+
16
+ const hasButtonSlot = computed(() => {
17
+ return Settings.dropButtonSlot !== '';
18
+ }),
19
+ buttonSlot = computed(() => {
20
+ return Settings.dropButtonSlot;
21
+ }),
22
+ computedText = computed(() => {
23
+ if (props.text.startsWith('__:')) {
24
+ return __(props.text.substring(3));
25
+ }
26
+ return props.text;
27
+ })
28
+ </script>
29
+
30
+ <template>
31
+ <lkt-button
32
+ palette="table-delete"
33
+ :disabled="disabled"
34
+ @click.prevent.stop="emit('click')">
35
+ <template v-if="hasButtonSlot">
36
+ <component
37
+ :is="buttonSlot"/>
38
+ </template>
39
+ <template v-else>
40
+ <i class=""/> {{computedText}}
41
+ </template>
42
+ </lkt-button>
43
+ </template>
@@ -1,26 +1,33 @@
1
- <script lang="ts">
2
- export default {name: "LktHiddenRow", inheritAttrs: false}
3
- </script>
4
-
5
1
  <script lang="ts" setup>
6
2
  import {createLktEvent} from "lkt-events";
7
3
  import {getColumnDisplayContent} from "../functions/table-functions";
8
4
  import {LktTableColumn} from "../instances/LktTableColumn";
9
5
  import LktTableCell from "./LktTableCell.vue";
10
- import {ref, watch, PropType} from "vue";
6
+ import {ref, watch} from "vue";
7
+ import {LktObject} from "lkt-ts-interfaces";
11
8
 
12
9
  const emit = defineEmits(['update:modelValue', 'click']);
13
10
 
14
- const props = defineProps({
15
- isDraggable: {type: Boolean, default: true},
16
- sortable: {type: Boolean, default: true},
17
- i: {type: [Number], default: 0},
18
- hiddenColumnsColSpan: {type: Number, default: 0},
19
- visibleColumns: {type: Array as PropType<LktTableColumn[]>, default: (): LktTableColumn[] => []},
20
- hiddenColumns: {type: Array as PropType<LktTableColumn[]>, default: (): LktTableColumn[] => []},
21
- emptyColumns: {type: Array as PropType<string[]>, default: (): string[] => []},
22
- hiddenIsVisible: {type: Boolean, default: false},
23
- modelValue: {type: Object as PropType<any>, default: () => ({})},
11
+ const props = withDefaults(defineProps<{
12
+ modelValue: LktObject
13
+ isDraggable: boolean
14
+ sortable: boolean
15
+ hiddenIsVisible: boolean
16
+ i: number
17
+ hiddenColumnsColSpan: number
18
+ visibleColumns: LktTableColumn[]
19
+ hiddenColumns: LktTableColumn[]
20
+ emptyColumns: string[]
21
+ }>(), {
22
+ modelValue: () => ({}),
23
+ isDraggable: true,
24
+ sortable: true,
25
+ hiddenIsVisible: false,
26
+ i: 0,
27
+ hiddenColumnsColSpan: 0,
28
+ visibleColumns: () => [],
29
+ hiddenColumns: () => [],
30
+ emptyColumns: () => [],
24
31
  });
25
32
 
26
33
  const item = ref(props.modelValue);
@@ -45,17 +52,17 @@ watch(item, () => emit('update:modelValue', item.value));
45
52
  <tr :data-i="i">
46
53
  <td v-for="(column, i) in hiddenColumns"
47
54
  v-bind:data-column="column.key"
48
- v-bind:title="getColumnDisplayContent (column, item, i)"
55
+ v-bind:title="getColumnDisplayContent (column, item, i, hiddenColumns)"
49
56
  v-on:click="onClick($event, item, column)">
50
57
  <template v-if="!!$slots[column.key]">
51
58
  <slot v-bind:name="column.key"
52
59
  v-bind:value="item[column.key]"
53
60
  v-bind:item="item"
54
61
  v-bind:column="column"
55
- v-bind:i="i"></slot>
62
+ v-bind:i="i"/>
56
63
  </template>
57
64
  <template v-else>
58
- <lkt-table-cell :column="column" v-model="item" :i="i"></lkt-table-cell>
65
+ <lkt-table-cell :column="column" :columns="hiddenColumns" v-model="item" :i="i"/>
59
66
  </template>
60
67
  </td>
61
68
  </tr>
@@ -1,19 +1,23 @@
1
- <script lang="ts">
2
- export default {name: "LktTableCell", inheritAttrs: false}
3
- </script>
4
-
5
1
  <script lang="ts" setup>
6
2
  import {getColumnDisplayContent} from "../functions/table-functions";
7
3
  import {LktTableColumn} from "../instances/LktTableColumn";
8
- import {nextTick, ref, watch, PropType, computed} from "vue";
4
+ import {nextTick, ref, watch, computed} from "vue";
9
5
  import {LktObject} from "lkt-ts-interfaces";
10
6
 
11
- const emit = defineEmits(['edited']);
7
+ const emit = defineEmits(['update:modelValue']);
12
8
 
13
- const props = defineProps({
14
- modelValue: {type: Object as PropType<LktObject>, default: () => ({})},
15
- column: {type: Object as PropType<LktTableColumn>, default: () => ({})},
16
- i: {type: [Number], default: 0},
9
+ const props = withDefaults(defineProps<{
10
+ modelValue: LktObject
11
+ column: LktTableColumn
12
+ columns: LktTableColumn[]
13
+ i: number
14
+ editModeEnabled: boolean
15
+ }>(), {
16
+ modelValue: () => ({}),
17
+ column: () => ({}),
18
+ columns: () => [],
19
+ i: 0,
20
+ editModeEnabled: false
17
21
  });
18
22
 
19
23
  const item = ref(props.modelValue),
@@ -21,10 +25,10 @@ const item = ref(props.modelValue),
21
25
  inputElement = ref(null),
22
26
  loadingColumn = ref(props.column.showLoading());
23
27
 
24
- watch(value, () => {
28
+ watch(value, (v) => {
25
29
  const payload = JSON.parse(JSON.stringify(item.value));
26
- payload[props.column.key] = value.value;
27
- emit('edited', payload, props.i);
30
+ payload[props.column.key] = v;
31
+ emit('update:modelValue', payload);
28
32
  })
29
33
 
30
34
  watch(() => props.modelValue, (v) => {
@@ -56,44 +60,47 @@ const slotData = computed(() => {
56
60
  </template>
57
61
  <template v-else-if="column.type === 'text'">
58
62
  <lkt-field-text
59
- v-bind:read-mode="!column.editable"
63
+ v-bind:read-mode="!column.editable || !editModeEnabled"
60
64
  :ref="(el:any) => inputElement = el"
61
65
  :edit-slot="column.editSlot"
62
66
  :value-slot="column.valueSlot"
63
67
  :slot-data="slotData"
64
- v-model="value"></lkt-field-text>
68
+ v-model="value"/>
65
69
  </template>
66
70
  <template v-else-if="column.type === 'email'">
67
71
  <lkt-field-text
68
- v-bind:read-mode="!column.editable"
72
+ v-bind:read-mode="!column.editable || !editModeEnabled"
69
73
  :ref="(el:any) => inputElement = el"
70
74
  :edit-slot="column.editSlot"
71
75
  :value-slot="column.valueSlot"
72
76
  :slot-data="slotData"
73
77
  is-email
74
- v-model="value"></lkt-field-text>
78
+ v-model="value"/>
75
79
  </template>
76
80
  <template v-else-if="column.type === 'tel'">
77
81
  <lkt-field-text
78
- v-bind:read-mode="!column.editable"
82
+ v-bind:read-mode="!column.editable || !editModeEnabled"
79
83
  :ref="(el:any) => inputElement = el"
80
84
  :edit-slot="column.editSlot"
81
85
  :value-slot="column.valueSlot"
82
86
  :slot-data="slotData"
83
87
  is-tel
84
- v-model="value"></lkt-field-text>
88
+ v-model="value"/>
85
89
  </template>
86
90
  <template v-else-if="column.type === 'check'">
87
- <lkt-field-switch is-check v-bind:read-mode="!column.editable" :ref="(el:any) => inputElement = el" v-model="value"></lkt-field-switch>
91
+ <lkt-field-switch is-check v-bind:read-mode="!column.editable || !editModeEnabled" :ref="(el:any) => inputElement = el" v-model="value"/>
88
92
  </template>
89
93
  <template v-else-if="column.type === 'switch'">
90
- <lkt-field-switch v-bind:read-mode="!column.editable" :ref="(el:any) => inputElement = el" v-model="value"></lkt-field-switch>
94
+ <lkt-field-switch v-bind:read-mode="!column.editable || !editModeEnabled" :ref="(el:any) => inputElement = el" v-model="value"/>
95
+ </template>
96
+ <template v-else-if="column.type === 'file'">
97
+ <lkt-field-file v-bind:read-mode="!column.editable || !editModeEnabled" :ref="(el:any) => inputElement = el" v-model="value"/>
91
98
  </template>
92
99
  <template v-else-if="column.type === 'select'">
93
100
  <lkt-loader v-if="loadingColumn"></lkt-loader>
94
101
  <lkt-field-select
95
102
  v-else
96
- v-bind:read-mode="!column.editable"
103
+ v-bind:read-mode="!column.editable || !editModeEnabled"
97
104
  :ref="(el:any) => inputElement = el"
98
105
  v-model="value"
99
106
  :slot-data="slotData"
@@ -102,10 +109,11 @@ const slotData = computed(() => {
102
109
  v-bind:resource-data="column.resourceData"
103
110
  v-bind:options="column.options"
104
111
  v-bind:multiple="column.isMultiple"
112
+ v-bind:tags="column.tags"
105
113
  v-bind:multiple-display="column.multipleDisplay"
106
- v-bind:multiple-display-edition="column.multipleDisplayEdition"></lkt-field-select>
114
+ v-bind:multiple-display-edition="column.multipleDisplayEdition"/>
107
115
  </template>
108
116
  <template v-else>
109
- {{ getColumnDisplayContent(column, item, i) }}
117
+ {{ getColumnDisplayContent(column, item, i, columns) }}
110
118
  </template>
111
119
  </template>
@@ -1,71 +1,149 @@
1
- <script lang="ts">
2
- export default {name: "LktTableRow", inheritAttrs: false}
3
- </script>
4
-
5
1
  <script lang="ts" setup>
6
2
  import {createLktEvent} from "lkt-events";
7
3
  import {getColumnDisplayContent, getHorizontalColSpan, canRenderColumn} from "../functions/table-functions";
8
4
  import {LktTableColumn} from "../instances/LktTableColumn";
9
5
  import LktTableCell from "./LktTableCell.vue";
10
- import {ref, watch, PropType} from "vue";
6
+ import {ref, watch, computed} from "vue";
11
7
  import {LktObject} from "lkt-ts-interfaces";
8
+ import {Settings} from "../settings/Settings";
9
+ import DropButton from "./DropButton.vue";
10
+ import CreateButton from "./CreateButton.vue";
12
11
 
13
- const emit = defineEmits(['edited', 'click', 'show']);
12
+ const emit = defineEmits(['update:modelValue', 'click', 'show', 'item-up', 'item-down', 'item-drop']);
14
13
 
15
- const props = defineProps({
16
- isDraggable: {type: Boolean, default: true},
17
- sortable: {type: Boolean, default: true},
18
- i: {type: [Number], default: 0},
19
- displayHiddenColumnsIndicator: {type: Boolean, default: false},
20
- visibleColumns: {type: Array as PropType<LktTableColumn[]>, default: (): LktTableColumn[] => []},
21
- emptyColumns: {type: Array as PropType<string[]>, default: (): string[] => []},
22
- hiddenIsVisible: {type: Boolean, default: false},
23
- item: {type: Object as PropType<any>, default: () => ({})},
14
+ const props = withDefaults(defineProps<{
15
+ modelValue: LktObject
16
+ isDraggable: boolean
17
+ sortable: boolean
18
+ displayHiddenColumnsIndicator: boolean
19
+ hiddenIsVisible: boolean
20
+ addNavigation: boolean
21
+ latestRow: boolean
22
+ canDrop: boolean
23
+ editModeEnabled: boolean
24
+ i: number
25
+ visibleColumns: LktTableColumn[]
26
+ emptyColumns: string[]
27
+ dropConfirm: string
28
+ dropText: string
29
+ }>(), {
30
+ modelValue: () => ({}),
31
+ isDraggable: true,
32
+ sortable: true,
33
+ displayHiddenColumnsIndicator: false,
34
+ hiddenIsVisible: false,
35
+ addNavigation: false,
36
+ latestRow: false,
37
+ canDrop: false,
38
+ editModeEnabled: false,
39
+ i: 0,
40
+ visibleColumns: () => [],
41
+ emptyColumns: () => [],
42
+ dropConfirm: '',
43
+ dropText: '',
24
44
  });
25
45
 
26
- const Item = ref(props.item);
46
+ const Item = ref(props.modelValue);
27
47
 
28
48
  const onClick = ($event: any, item: any, column: LktTableColumn) => {
29
- emit('click', $event, createLktEvent('', {item, column}))
30
- };
31
- const onShow = ($event: any, i: any) => {
32
- emit('show', $event, createLktEvent('', {i}))
33
- };
34
-
35
- const onEdited = (payload: LktObject, i: any) => {
36
- Item.value = payload;
37
- }
49
+ emit('click', $event, createLktEvent('', {item, column}))
50
+ },
51
+ onShow = ($event: any, i: any) => {
52
+ emit('show', $event, createLktEvent('', {i}))
53
+ },
54
+ classes = computed(() => {
55
+ let r = [];
56
+ if (props.sortable && props.isDraggable) r.push('handle');
57
+ return r.join(' ');
58
+ }),
59
+ hasNavButtonSlot = computed(() => {
60
+ return Settings.navButtonSlot !== '';
61
+ }),
62
+ navButtonSlot = computed(() => {
63
+ return Settings.navButtonSlot;
64
+ }),
65
+ hasDropButtonSlot = computed(() => {
66
+ return Settings.dropButtonSlot !== '';
67
+ }),
68
+ dropButtonSlot = computed(() => {
69
+ return Settings.dropButtonSlot;
70
+ }),
71
+ onClickUp = () => {
72
+ emit('item-up', props.i);
73
+ },
74
+ onClickDown = () => {
75
+ emit('item-down', props.i);
76
+ },
77
+ onClickDrop = () => {
78
+ emit('item-drop', props.i);
79
+ };
38
80
 
39
- watch(() => props.item, (v) => Item.value = v);
40
- watch(Item, () => emit('edited', Item.value, props.i));
81
+ watch(() => props.modelValue, (v) => Item.value = v);
82
+ watch(Item, (v) => {
83
+ emit('update:modelValue', v, props.i)
84
+ }, {deep: true});
41
85
  </script>
42
86
 
43
87
  <template>
44
- <tr :data-i="i" :data-handle-drag="isDraggable">
45
- <td v-if="sortable && isDraggable" data-role="drag-indicator"></td>
46
- <td v-else-if="sortable" data-role="invalid-drag-indicator"></td>
88
+ <tr :data-i="i" :data-draggable="isDraggable">
89
+ <td v-if="sortable && isDraggable && editModeEnabled" data-role="drag-indicator" :class="classes" />
90
+ <td v-else-if="sortable && editModeEnabled" data-role="invalid-drag-indicator"/>
91
+ <td v-if="addNavigation && editModeEnabled" class="lkt-table-nav-cell">
92
+ <div class="lkt-table-nav-container">
93
+ <lkt-button palette="table-nav" :disabled="i === 0" @click="onClickUp">
94
+ <template v-if="hasNavButtonSlot">
95
+ <component
96
+ :is="navButtonSlot"
97
+ direction="up"/>
98
+ </template>
99
+ <template v-else>
100
+ <i class=""/> UP
101
+ </template>
102
+ </lkt-button>
103
+ <lkt-button palette="table-nav" :disabled="latestRow" @click="onClickDown">
104
+ <template v-if="hasNavButtonSlot">
105
+ <component
106
+ :is="navButtonSlot"
107
+ direction="down"/>
108
+ </template>
109
+ <template v-else>
110
+ <i class=""/> DOWN
111
+ </template>
112
+ </lkt-button>
113
+ </div>
114
+ </td>
47
115
  <td v-if="displayHiddenColumnsIndicator"
48
116
  v-on:click="onShow($event, i)" data-role="show-more"
49
- v-bind:class="hiddenIsVisible ? 'state-open' : ''"></td>
117
+ v-bind:class="hiddenIsVisible ? 'state-open' : ''"/>
50
118
  <template v-for="column in visibleColumns">
51
- <td v-if="canRenderColumn(column, emptyColumns, item)"
119
+ <td v-if="canRenderColumn(column, emptyColumns, Item)"
52
120
  v-bind:data-column="column.key"
53
- v-bind:colspan="getHorizontalColSpan(column,item)"
54
- v-bind:title="getColumnDisplayContent (column, item, i)"
55
- v-on:click="onClick($event, item, column)"
121
+ v-bind:colspan="getHorizontalColSpan(column,Item)"
122
+ v-bind:title="getColumnDisplayContent (column, Item, i, visibleColumns)"
123
+ v-on:click="onClick($event, Item, column)"
56
124
  >
57
125
  <template v-if="!!$slots[column.key]">
58
126
  <slot v-bind:name="column.key"
59
- v-bind:value="item[column.key]"
60
- v-bind:item="item"
127
+ v-bind:value="Item[column.key]"
128
+ v-bind:item="Item"
61
129
  v-bind:column="column"
62
- v-bind:i="i"></slot>
130
+ v-bind:i="i"/>
63
131
  </template>
64
- <template v-else-if="item">
65
- <lkt-table-cell :column="column" v-model="Item" :i="i" v-on:edited="onEdited"></lkt-table-cell>
132
+ <template v-else-if="Item">
133
+ <lkt-table-cell
134
+ v-model="Item"
135
+ :column="column"
136
+ :columns="visibleColumns"
137
+ :edit-mode-enabled="editModeEnabled"
138
+ :i="i"/>
66
139
  </template>
67
140
  </td>
68
141
  </template>
142
+ <td v-if="canDrop && editModeEnabled" class="lkt-table-delete-cell">
143
+ <drop-button
144
+ :text="dropText"
145
+ @click="onClickDrop"/>
146
+ </td>
69
147
  </tr>
70
148
 
71
149
  </template>
@@ -0,0 +1,60 @@
1
+ <script setup lang="ts">
2
+
3
+ import {getVerticalColSpan} from "../functions/table-functions";
4
+ import {LktTableColumn} from "../instances/LktTableColumn";
5
+ import {computed} from "vue";
6
+ import {LktObject} from "lkt-ts-interfaces";
7
+ import {__} from "lkt-i18n";
8
+
9
+ const emit = defineEmits(['click']);
10
+
11
+ const props = withDefaults(defineProps<{
12
+ column: LktTableColumn,
13
+ sortBy: string,
14
+ sortDirection: string,
15
+ amountOfColumns: number,
16
+ items: LktObject[]
17
+ }>(), {
18
+ column: () => ({}),
19
+ items: () => [],
20
+ isDraggable: true,
21
+ sortBy: '',
22
+ sortDirection: '',
23
+ amountOfColumns: 0
24
+ });
25
+
26
+ const computedColSpan = computed(() => {
27
+ return getVerticalColSpan(props.column, props.amountOfColumns, props.items);
28
+ }),
29
+ computedSortable = computed(() => {
30
+ return props.column.sortable === true;
31
+ }),
32
+ computedSortDirection = computed(() => {
33
+ if (!computedSortable.value) return '';
34
+ if (props.sortBy === props.column.key) return props.sortDirection;
35
+ return '';
36
+ }),
37
+ computedLabel = computed(() => {
38
+ if (props.column.label.startsWith('__:')) {
39
+ return __(props.column.label.substring(3));
40
+ }
41
+ return props.column.label;
42
+ });
43
+
44
+ const onClick = () => {
45
+ emit('click', props.column);
46
+ }
47
+
48
+ </script>
49
+
50
+ <template>
51
+ <th :data-column="column.key"
52
+ :data-sortable="computedSortable"
53
+ :data-sort="computedSortDirection"
54
+ :colspan="computedColSpan"
55
+ :title="computedLabel"
56
+ v-on:click="onClick"
57
+ >
58
+ <div>{{ computedLabel }}</div>
59
+ </th>
60
+ </template>