@finema/core 3.15.1 → 3.16.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/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "3.15.1",
3
+ "version": "3.16.0",
4
4
  "configKey": "core",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
package/dist/module.mjs CHANGED
@@ -4,7 +4,7 @@ import * as lodash from 'lodash-es';
4
4
  import * as theme from '../dist/runtime/theme/index.js';
5
5
 
6
6
  const name = "@finema/core";
7
- const version = "3.15.1";
7
+ const version = "3.16.0";
8
8
 
9
9
  const nuxtAppOptions = {
10
10
  head: {
@@ -13,15 +13,15 @@
13
13
  :icon="icon"
14
14
  :ui="ui"
15
15
  :ignore-filter="ignoreFilter"
16
- :leading-icon="options.find((item) => item.value === value)?.icon"
17
- :avatar="options.find((item) => item.value === value)?.avatar"
16
+ :leading-icon="options.find((item2) => item2.value === value)?.icon"
17
+ :avatar="options.find((item2) => item2.value === value)?.avatar"
18
18
  @update:modelValue="onChange"
19
19
  @update:searchTerm="onSearch"
20
20
  >
21
21
  <template #default="{ modelValue, ui: selectMenuUi }">
22
22
  <Chip
23
- v-if="options.find((item) => item.value === modelValue)?.chip"
24
- v-bind="options.find((item) => item.value === modelValue)?.chip"
23
+ v-if="options.find((item2) => item2.value === modelValue)?.chip"
24
+ v-bind="options.find((item2) => item2.value === modelValue)?.chip"
25
25
  inset
26
26
  standalone
27
27
  :size="selectMenuUi.itemLeadingChipSize()"
@@ -35,25 +35,31 @@
35
35
  })
36
36
  "
37
37
  >
38
- <component
39
- :is="selectedOption.component"
40
- v-if="componentPosition === 'leading' && selectedOption?.component"
41
- v-bind="selectedOption.componentProps"
42
- />
43
- <span
44
- :class="
38
+ <div class="flex items-center gap-x-2">
39
+ <component
40
+ :is="selectedOption.component"
41
+ v-if="
42
+ componentPosition === 'leading' && selectedOption?.component
43
+ "
44
+ v-bind="selectedOption.componentProps"
45
+ />
46
+ <span
47
+ :class="
45
48
  theme.selectedLabel({
46
49
  class: [ui?.selectedLabel]
47
50
  })
48
51
  "
49
- >
50
- {{ selectedOption?.label ?? modelValue }}
51
- </span>
52
- <component
53
- :is="selectedOption.component"
54
- v-if="componentPosition === 'trailing' && selectedOption?.component"
55
- v-bind="selectedOption.componentProps"
56
- />
52
+ >
53
+ {{ selectedOption?.label ?? modelValue }}
54
+ </span>
55
+ <component
56
+ :is="selectedOption.component"
57
+ v-if="
58
+ componentPosition === 'trailing' && selectedOption?.component
59
+ "
60
+ v-bind="selectedOption.componentProps"
61
+ />
62
+ </div>
57
63
  <Icon
58
64
  v-if="clearable"
59
65
  :name="clearIcon"
@@ -66,6 +72,46 @@
66
72
  />
67
73
  </div>
68
74
  </template>
75
+
76
+ <template #item="{ item }">
77
+ <div
78
+ v-if="item?.type === 'separator'"
79
+ class="my-1 h-px bg-gray-200"
80
+ />
81
+ <div
82
+ v-else
83
+ class="flex items-center gap-x-2"
84
+ >
85
+ <Chip
86
+ v-if="item?.chip"
87
+ v-bind="item.chip"
88
+ inset
89
+ standalone
90
+ size="2xs"
91
+ />
92
+ <Icon
93
+ v-if="item?.icon"
94
+ :name="item.icon"
95
+ class="size-4"
96
+ />
97
+ <Avatar
98
+ v-if="item?.avatar"
99
+ v-bind="item.avatar"
100
+ size="2xs"
101
+ />
102
+ <component
103
+ :is="item?.component"
104
+ v-if="componentPosition === 'leading' && item?.component"
105
+ v-bind="item?.componentProps"
106
+ />
107
+ <span class="truncate">{{ item?.label ?? item?.value }}</span>
108
+ <component
109
+ :is="item?.component"
110
+ v-if="componentPosition === 'trailing' && item?.component"
111
+ v-bind="item?.componentProps"
112
+ />
113
+ </div>
114
+ </template>
69
115
  </SelectMenu>
70
116
  </FieldWrapper>
71
117
  </template>
@@ -36,21 +36,21 @@
36
36
  "
37
37
  >
38
38
  <Chip
39
- v-if="options.find((item) => item.value === _value)?.chip"
40
- v-bind="options.find((item) => item.value === _value)?.chip"
39
+ v-if="options.find((item2) => item2.value === _value)?.chip"
40
+ v-bind="options.find((item2) => item2.value === _value)?.chip"
41
41
  inset
42
42
  standalone
43
43
  :size="selectMenuUi.itemLeadingChipSize()"
44
44
  class="p-1"
45
45
  />
46
46
  <Icon
47
- v-if="options.find((item) => item.value === _value)?.icon"
48
- :name="options.find((item) => item.value === _value)?.icon"
47
+ v-if="options.find((item2) => item2.value === _value)?.icon"
48
+ :name="options.find((item2) => item2.value === _value)?.icon"
49
49
  class="size-4"
50
50
  />
51
51
  <Avatar
52
- v-if="options.find((item) => item.value === _value)?.avatar"
53
- v-bind="options.find((item) => item.value === _value)?.avatar"
52
+ v-if="options.find((item2) => item2.value === _value)?.avatar"
53
+ v-bind="options.find((item2) => item2.value === _value)?.avatar"
54
54
  :class="selectMenuUi.itemLeadingAvatar()"
55
55
  size="2xs"
56
56
  />
@@ -93,6 +93,46 @@
93
93
  </div>
94
94
  </div>
95
95
  </template>
96
+
97
+ <template #item="{ item }">
98
+ <div
99
+ v-if="item?.type === 'separator'"
100
+ class="my-1 h-px bg-gray-200"
101
+ />
102
+ <div
103
+ v-else
104
+ class="flex items-center gap-x-2"
105
+ >
106
+ <Chip
107
+ v-if="item?.chip"
108
+ v-bind="item.chip"
109
+ inset
110
+ standalone
111
+ size="2xs"
112
+ />
113
+ <Icon
114
+ v-if="item?.icon"
115
+ :name="item.icon"
116
+ class="size-4"
117
+ />
118
+ <Avatar
119
+ v-if="item?.avatar"
120
+ v-bind="item.avatar"
121
+ size="2xs"
122
+ />
123
+ <component
124
+ :is="item?.component"
125
+ v-if="componentPosition === 'leading' && item?.component"
126
+ v-bind="item?.componentProps"
127
+ />
128
+ <span class="truncate">{{ item?.label ?? item?.value }}</span>
129
+ <component
130
+ :is="item?.component"
131
+ v-if="componentPosition === 'trailing' && item?.component"
132
+ v-bind="item?.componentProps"
133
+ />
134
+ </div>
135
+ </template>
96
136
  </SelectMenu>
97
137
  </FieldWrapper>
98
138
  </template>
@@ -3,16 +3,17 @@ import { tableTheme } from '#core/theme/table';
3
3
  type __VLS_Props = {
4
4
  options: ITableOptions<any> & ISimpleTableOptions<any>;
5
5
  ui?: (typeof tableTheme)['slots'];
6
+ to?: string | ((row: any) => any);
6
7
  };
7
- declare var __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_45: any, __VLS_46: any;
8
+ declare var __VLS_25: {}, __VLS_32: {}, __VLS_34: {}, __VLS_53: any, __VLS_54: any;
8
9
  type __VLS_Slots = {} & {
9
- [K in NonNullable<typeof __VLS_45>]?: (props: typeof __VLS_46) => any;
10
+ [K in NonNullable<typeof __VLS_53>]?: (props: typeof __VLS_54) => any;
10
11
  } & {
11
- loading?: (props: typeof __VLS_22) => any;
12
+ loading?: (props: typeof __VLS_25) => any;
12
13
  } & {
13
- error?: (props: typeof __VLS_29) => any;
14
+ error?: (props: typeof __VLS_32) => any;
14
15
  } & {
15
- error?: (props: typeof __VLS_31) => any;
16
+ error?: (props: typeof __VLS_34) => any;
16
17
  };
17
18
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
19
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -23,6 +23,7 @@
23
23
  :data="options.rawData"
24
24
  v-bind="$attrs"
25
25
  :ui="ui"
26
+ @select="onSelect"
26
27
  >
27
28
  <template #loading>
28
29
  <Loader :loading="true" />
@@ -53,24 +54,41 @@
53
54
  </slot>
54
55
  </template>
55
56
  <template
56
- v-for="column in options.columns.filter((item) => !!item.type)"
57
+ v-for="column in options.columns"
57
58
  #[`${column.accessorKey}-cell`]="{ row }"
58
59
  :key="column.accessorKey"
59
60
  >
60
- <component
61
- :is="
61
+ <NuxtLink
62
+ v-if="to && column.accessorKey !== 'actions'"
63
+ :to="resolveTo(row.original)"
64
+ class="absolute inset-0"
65
+ tabindex="-1"
66
+ aria-hidden="true"
67
+ />
68
+ <div
69
+ :class="
70
+ to && column.accessorKey !== 'actions' ? 'pointer-events-none relative z-10' : 'relative z-10'
71
+ "
72
+ >
73
+ <component
74
+ :is="
62
75
  column.type === COLUMN_TYPES.COMPONENT ? column.component : columnTypeComponents[column.type]
63
76
  "
64
- v-if="
77
+ v-if="
65
78
  column.type === COLUMN_TYPES.COMPONENT || columnTypeComponents[column.type]
66
79
  "
67
- :value="transformValue(column, row)"
68
- :column="column"
69
- :row="row"
70
- />
80
+ :value="transformValue(column, row)"
81
+ :column="column"
82
+ :row="row"
83
+ />
84
+ <template v-else>
85
+ {{ transformValue(column, row) }}
86
+ </template>
87
+ </div>
71
88
  </template>
72
89
  <template
73
90
  v-for="(_, slotName) of $slots"
91
+ :key="slotName"
74
92
  #[slotName]="slotProps"
75
93
  >
76
94
  <slot
@@ -113,10 +131,11 @@ import ColumnText from "#core/components/Table/ColumnText.vue";
113
131
  import UTable from "#ui/components/Table";
114
132
  import Pagination from "./Pagination.vue";
115
133
  import { tableTheme } from "#core/theme/table";
116
- const emits = defineEmits(["pageChange", "search"]);
134
+ const emits = defineEmits(["pageChange", "search", "select"]);
117
135
  const props = defineProps({
118
136
  options: { type: Object, required: true },
119
- ui: { type: null, required: false }
137
+ ui: { type: null, required: false },
138
+ to: { type: [String, Function], required: false }
120
139
  });
121
140
  const columnTypeComponents = {
122
141
  [COLUMN_TYPES.NUMBER]: ColumnNumber,
@@ -128,7 +147,9 @@ const columnTypeComponents = {
128
147
  const theme = computed(() => useUiConfig(tableTheme, "table")());
129
148
  const config = useAppConfig();
130
149
  const page = ref(props.options.pageOptions?.currentPage || 1);
131
- const pageLimit = ref(props.options.pageOptions?.limit || config.core.limit_per_page);
150
+ const pageLimit = ref(
151
+ props.options.pageOptions?.limit || config.core.limit_per_page
152
+ );
132
153
  const uTableCompatibleColumns = computed(
133
154
  () => props.options.columns.map((col) => ({
134
155
  ...col,
@@ -137,9 +158,18 @@ const uTableCompatibleColumns = computed(
137
158
  }))
138
159
  );
139
160
  const transformValue = (column, row) => {
140
- return column.cell ? column.cell({
141
- row
142
- }) : row.getValue(column.accessorKey);
161
+ if (typeof column.cell === "function") {
162
+ return column.cell({
163
+ row
164
+ });
165
+ }
166
+ return row.getValue(column.accessorKey);
167
+ };
168
+ const resolveTo = (rowOriginal) => {
169
+ if (typeof props.to === "function") {
170
+ return props.to(rowOriginal);
171
+ }
172
+ return props.to;
143
173
  };
144
174
  useWatchChange(
145
175
  () => props.options.pageOptions?.currentPage,
@@ -151,6 +181,9 @@ const onPageChange = (newPage) => {
151
181
  page.value = newPage;
152
182
  emits("pageChange", newPage);
153
183
  };
184
+ const onSelect = (rows) => {
185
+ emits("select", rows);
186
+ };
154
187
  const changePageLimit = (limit) => {
155
188
  pageLimit.value = limit;
156
189
  props.options.repo.fetchPageChange(1, {
@@ -3,16 +3,17 @@ import { tableTheme } from '#core/theme/table';
3
3
  type __VLS_Props = {
4
4
  options: ITableOptions<any> & ISimpleTableOptions<any>;
5
5
  ui?: (typeof tableTheme)['slots'];
6
+ to?: string | ((row: any) => any);
6
7
  };
7
- declare var __VLS_22: {}, __VLS_29: {}, __VLS_31: {}, __VLS_45: any, __VLS_46: any;
8
+ declare var __VLS_25: {}, __VLS_32: {}, __VLS_34: {}, __VLS_53: any, __VLS_54: any;
8
9
  type __VLS_Slots = {} & {
9
- [K in NonNullable<typeof __VLS_45>]?: (props: typeof __VLS_46) => any;
10
+ [K in NonNullable<typeof __VLS_53>]?: (props: typeof __VLS_54) => any;
10
11
  } & {
11
- loading?: (props: typeof __VLS_22) => any;
12
+ loading?: (props: typeof __VLS_25) => any;
12
13
  } & {
13
- error?: (props: typeof __VLS_29) => any;
14
+ error?: (props: typeof __VLS_32) => any;
14
15
  } & {
15
- error?: (props: typeof __VLS_31) => any;
16
+ error?: (props: typeof __VLS_34) => any;
16
17
  };
17
18
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, any, string, import("vue").PublicProps, any, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
18
19
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -12,10 +12,12 @@ type __VLS_Props = {
12
12
  left: string[];
13
13
  right: string[];
14
14
  };
15
+ to?: string | ((row: any) => any);
15
16
  };
16
17
  type __VLS_Slots = Slot;
17
18
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
18
19
  search: (q: string) => any;
20
+ select: (rows: any[]) => any;
19
21
  pageChange: (page: number) => any;
20
22
  "update:columnPinning": (value: {
21
23
  left: string[];
@@ -23,6 +25,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
23
25
  }) => any;
24
26
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
25
27
  onSearch?: ((q: string) => any) | undefined;
28
+ onSelect?: ((rows: any[]) => any) | undefined;
26
29
  onPageChange?: ((page: number) => any) | undefined;
27
30
  "onUpdate:columnPinning"?: ((value: {
28
31
  left: string[];
@@ -17,10 +17,12 @@
17
17
  <Base
18
18
  v-bind="$attrs"
19
19
  :options="options"
20
- :ui="ui"
20
+ :ui="computedUi"
21
21
  :column-pinning="computedColumnPinning"
22
+ :to="to"
22
23
  @page-change="onPageChange"
23
24
  @search="emits('search', q)"
25
+ @select="emits('select', $event)"
24
26
  >
25
27
  <template
26
28
  v-for="(_, slot) of $slots"
@@ -40,7 +42,7 @@ import { computed } from "vue";
40
42
  import { _debounce, ref, useUiConfig, watch } from "#imports";
41
43
  import { tableTheme } from "#core/theme/table";
42
44
  import Base from "#core/components/Table/Base.vue";
43
- const emits = defineEmits(["pageChange", "search", "update:columnPinning"]);
45
+ const emits = defineEmits(["pageChange", "search", "select", "update:columnPinning"]);
44
46
  const props = defineProps({
45
47
  options: { type: Object, required: true },
46
48
  ui: { type: null, required: false },
@@ -48,12 +50,22 @@ const props = defineProps({
48
50
  columnPinning: { type: Object, required: false, default: () => ({
49
51
  left: [],
50
52
  right: []
51
- }) }
53
+ }) },
54
+ to: { type: [String, Function], required: false }
52
55
  });
53
56
  defineSlots();
54
57
  const tableContainer = ref();
55
58
  const q = ref(props.options?.pageOptions.search ?? "");
56
59
  const theme = computed(() => useUiConfig(tableTheme, "table")());
60
+ const computedUi = computed(() => {
61
+ if (!props.to) {
62
+ return props.ui;
63
+ }
64
+ return {
65
+ ...props.ui,
66
+ td: [props.ui?.td, "cursor-pointer", "relative"].filter(Boolean).join(" ")
67
+ };
68
+ });
57
69
  const computedColumnPinning = computed(() => {
58
70
  if (props.isPinAction) {
59
71
  const hasActionsColumn = props.options.columns.some(
@@ -12,10 +12,12 @@ type __VLS_Props = {
12
12
  left: string[];
13
13
  right: string[];
14
14
  };
15
+ to?: string | ((row: any) => any);
15
16
  };
16
17
  type __VLS_Slots = Slot;
17
18
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
18
19
  search: (q: string) => any;
20
+ select: (rows: any[]) => any;
19
21
  pageChange: (page: number) => any;
20
22
  "update:columnPinning": (value: {
21
23
  left: string[];
@@ -23,6 +25,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
23
25
  }) => any;
24
26
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
25
27
  onSearch?: ((q: string) => any) | undefined;
28
+ onSelect?: ((rows: any[]) => any) | undefined;
26
29
  onPageChange?: ((page: number) => any) | undefined;
27
30
  "onUpdate:columnPinning"?: ((value: {
28
31
  left: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "3.15.1",
3
+ "version": "3.16.0",
4
4
  "repository": "https://gitlab.finema.co/finema/ui-kit",
5
5
  "license": "MIT",
6
6
  "author": "Finema Dev Core Team",