@vc-shell/framework 1.0.168 → 1.0.170

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.
Files changed (49) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/core/types/index.ts +2 -2
  3. package/dist/core/types/index.d.ts +2 -2
  4. package/dist/core/types/index.d.ts.map +1 -1
  5. package/dist/framework.js +13519 -13295
  6. package/dist/index.css +1 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/shared/modules/assets/index.d.ts.map +1 -1
  9. package/dist/shared/modules/assets-manager/components/assets-manager/assets-manager.vue.d.ts.map +1 -1
  10. package/dist/shared/modules/assets-manager/index.d.ts.map +1 -1
  11. package/dist/shared/modules/dynamic/composables/useFilterBuilder/index.d.ts.map +1 -1
  12. package/dist/shared/modules/dynamic/composables/useToolbarReducer/index.d.ts +2 -2
  13. package/dist/shared/modules/dynamic/composables/useToolbarReducer/index.d.ts.map +1 -1
  14. package/dist/shared/modules/dynamic/pages/dynamic-blade-form.vue.d.ts.map +1 -1
  15. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts +3 -2
  16. package/dist/shared/modules/dynamic/pages/dynamic-blade-list.vue.d.ts.map +1 -1
  17. package/dist/shared/modules/dynamic/types/index.d.ts +7 -1
  18. package/dist/shared/modules/dynamic/types/index.d.ts.map +1 -1
  19. package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts.map +1 -1
  20. package/dist/tsconfig.tsbuildinfo +1 -1
  21. package/dist/ui/components/atoms/vc-container/vc-container.vue.d.ts.map +1 -1
  22. package/dist/ui/components/organisms/vc-gallery/_internal/vc-gallery-item/vc-gallery-item.vue.d.ts +1 -1
  23. package/dist/ui/components/organisms/vc-gallery/vc-gallery.vue.d.ts +1 -1
  24. package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue.d.ts +11 -4
  25. package/dist/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue.d.ts.map +1 -1
  26. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts +6 -3
  27. package/dist/ui/components/organisms/vc-table/vc-table.vue.d.ts.map +1 -1
  28. package/package.json +5 -4
  29. package/shared/modules/assets/index.ts +1 -2
  30. package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +24 -22
  31. package/shared/modules/assets-manager/index.ts +1 -2
  32. package/shared/modules/dynamic/composables/useFilterBuilder/index.ts +0 -1
  33. package/shared/modules/dynamic/composables/useToolbarReducer/index.ts +2 -2
  34. package/shared/modules/dynamic/helpers/override.ts +61 -9
  35. package/shared/modules/dynamic/pages/dynamic-blade-form.vue +4 -1
  36. package/shared/modules/dynamic/pages/dynamic-blade-list.vue +48 -4
  37. package/shared/modules/dynamic/types/index.ts +9 -1
  38. package/shared/pages/LoginPage/components/login/Login.vue +8 -5
  39. package/ui/components/atoms/vc-container/vc-container.vue +40 -8
  40. package/ui/components/organisms/vc-table/_internal/vc-table-mobile-item/vc-table-mobile-item.vue +171 -160
  41. package/ui/components/organisms/vc-table/vc-table.vue +13 -8
  42. package/dist/shared/modules/assets/locales/index.d.ts +0 -3
  43. package/dist/shared/modules/assets/locales/index.d.ts.map +0 -1
  44. package/dist/shared/modules/assets-manager/locales/index.d.ts +0 -3
  45. package/dist/shared/modules/assets-manager/locales/index.d.ts.map +0 -1
  46. package/shared/modules/assets/locales/en.json +0 -32
  47. package/shared/modules/assets/locales/index.ts +0 -2
  48. package/shared/modules/assets-manager/locales/en.json +0 -28
  49. package/shared/modules/assets-manager/locales/index.ts +0 -2
@@ -7,14 +7,13 @@
7
7
  <template v-if="isLogin">
8
8
  <VcForm @submit.prevent="login">
9
9
  <Field
10
- v-slot="{ field, errorMessage, handleChange, errors }"
10
+ v-slot="{ errorMessage, handleChange, errors }"
11
11
  :label="t('LOGIN.FIELDS.LOGIN.LABEL')"
12
12
  name="username"
13
13
  :model-value="form.username"
14
14
  rules="required"
15
15
  >
16
16
  <VcInput
17
- v-bind="field"
18
17
  ref="loginField"
19
18
  v-model="form.username"
20
19
  class="tw-mb-4 tw-mt-1"
@@ -27,14 +26,13 @@
27
26
  />
28
27
  </Field>
29
28
  <Field
30
- v-slot="{ field, errorMessage, handleChange, errors }"
29
+ v-slot="{ errorMessage, handleChange, errors }"
31
30
  :label="t('LOGIN.FIELDS.PASSWORD.LABEL')"
32
31
  name="password"
33
32
  :model-value="form.password"
34
33
  rules="required"
35
34
  >
36
35
  <VcInput
37
- v-bind="field"
38
36
  ref="passwordField"
39
37
  v-model="form.password"
40
38
  class="tw-mb-4"
@@ -78,6 +76,7 @@
78
76
  <div
79
77
  class="tw-flex tw-items-center tw-text-center tw-uppercase tw-text-[color:var(--separator-text)] before:tw-content-[''] before:tw-flex-1 before:tw-border-b before:tw-border-b-[color:var(--separator)] before:tw-mr-2 after:tw-content-[''] after:tw-flex-1 after:tw-border-b after:tw-border-b-[color:var(--separator)] after:tw-ml-2"
80
78
  >
79
+ <!-- TODO add to localization -->
81
80
  OR
82
81
  </div>
83
82
  <div class="tw-flex tw-justify-center tw-mt-4 tw-flex-wrap tw-gap-2">
@@ -198,7 +197,7 @@ const props = defineProps<Props>();
198
197
 
199
198
  const router = useRouter();
200
199
 
201
- useForm({ validateOnMount: false });
200
+ const { setFieldError, resetForm, setErrors, validateField } = useForm({ validateOnMount: false });
202
201
  const { uiSettings, loading: customizationLoading } = useSettings();
203
202
  const { t } = useI18n({ useScope: "global" });
204
203
  let useLogin;
@@ -253,6 +252,7 @@ const forgotPasswordForm = reactive({
253
252
 
254
253
  const login = async () => {
255
254
  if (isValid.value) {
255
+ signInResult.value.error = "";
256
256
  signInResult.value = (await signIn(form.username, form.password)) as SignInResult & {
257
257
  status?: number;
258
258
  error?: any;
@@ -264,6 +264,8 @@ const login = async () => {
264
264
  if (signInResult.value.status) {
265
265
  if (signInResult.value.status === 401) {
266
266
  signInResult.value.error = "The login or password is incorrect.";
267
+ form.password = "";
268
+ validateField("password");
267
269
  } else {
268
270
  signInResult.value.error = "Authentication error (code: " + signInResult.value.status + ").";
269
271
  }
@@ -288,6 +290,7 @@ const forgot = async () => {
288
290
 
289
291
  const togglePassRequest = () => {
290
292
  isLogin.value = !isLogin.value;
293
+ signInResult.value.error = "";
291
294
  if (isLogin.value) {
292
295
  forgotPasswordRequestSent.value = false;
293
296
  forgotPasswordForm.loginOrEmail = "";
@@ -24,10 +24,12 @@
24
24
  :style="{ height: dist ? `${dist}px` : '0px' }"
25
25
  >
26
26
  <VcIcon
27
- icon="fas fa-spinner"
28
- :style="{ 'tw-font-size': `${dist / 2}px` }"
29
- class="vc-container__overscroll-icon"
27
+ :icon="status === 'pulling' ? 'fas fa-arrow-down' : 'fas fa-sync'"
28
+ :class="[iconClass]"
29
+ :style="{ transform: status === 'pulling' ? `rotate(${dist * 3}deg)` : '' }"
30
30
  ></VcIcon>
31
+ <span v-if="status === 'pulling'">{{ $t("COMPONENTS.ATOMS.VC_CONTAINER.PULL_TO_REFRESH") }}</span>
32
+ <span v-else-if="status === 'loosing'">{{ $t("COMPONENTS.ATOMS.VC_CONTAINER.REFRESHING") }}</span>
31
33
  </div>
32
34
  <slot></slot>
33
35
  </div>
@@ -73,6 +75,15 @@ onMounted(() => {
73
75
 
74
76
  const touchable = computed(() => status.value !== "refresh" && status.value !== "success");
75
77
 
78
+ const iconClass = computed(() => {
79
+ if (status.value === "loosing") {
80
+ return "vc-container__overscroll-icon_refresh";
81
+ } else if (status.value === "pulling") {
82
+ return "vc-container__overscroll-icon_pulling";
83
+ }
84
+ return "vc-container__overscroll-icon";
85
+ });
86
+
76
87
  const scrollTop = () => {
77
88
  if (component.value) {
78
89
  component.value.scroll(0, 0);
@@ -178,15 +189,27 @@ defineExpose({
178
189
  }
179
190
 
180
191
  &__overscroll {
181
- @apply tw-relative tw-w-full tw-flex tw-items-start tw-justify-center tw-overflow-hidden;
192
+ @apply tw-relative tw-w-full tw-flex tw-items-start tw-justify-center tw-overflow-hidden tw-gap-2;
182
193
 
183
- &-icon {
184
- @apply tw-text-[color:#a1c0d4] tw-animate-spin;
194
+ &_passed {
195
+ @apply tw-text-[#43b0e6];
185
196
  }
197
+ }
186
198
 
187
- &_passed &-icon {
188
- @apply tw-text-[#43b0e6];
199
+ &__overscroll-icon {
200
+ @apply tw-text-[color:#a1c0d4];
201
+
202
+ &_pulling {
203
+ @apply tw-text-[color:#a1c0d4];
189
204
  }
205
+
206
+ &_refresh {
207
+ animation: tw-spin 2s linear infinite;
208
+ }
209
+ }
210
+
211
+ &__overscroll span {
212
+ @apply tw-mb-2 tw-text-sm tw-text-gray-500;
190
213
  }
191
214
 
192
215
  &__inner {
@@ -214,4 +237,13 @@ defineExpose({
214
237
  @apply tw-p-0;
215
238
  }
216
239
  }
240
+
241
+ @keyframes tw-spin {
242
+ from {
243
+ transform: rotate(0deg);
244
+ }
245
+ to {
246
+ transform: rotate(360deg);
247
+ }
248
+ }
217
249
  </style>
@@ -1,131 +1,131 @@
1
1
  <template>
2
2
  <div
3
- class="tw-relative tw-flex tw-flex-nowrap tw-items-stretch tw-transition tw-duration-200"
4
- :class="{ ' tw-transition-none': isMoving }"
5
- :style="`transform: translateX(${offsetX}px)`"
6
- @click="$emit('click')"
7
- @touchstart="touchStart"
8
- @touchmove="touchMove"
9
- @touchend="touchEnd"
10
- @touchcancel="touchCancel"
3
+ ref="container"
4
+ v-on-click-outside="reset"
5
+ v-touch:hold="handleHold"
6
+ class="tw-select-none tw-relative tw-overflow-hidden tw-flex"
7
+ @click="handleClick"
8
+ @contextmenu.prevent
11
9
  >
12
- <!-- Left swipe actions-->
13
10
  <div
14
- v-if="leftSwipeActions && leftSwipeActions.length"
15
- class="tw-flex-shrink-0 tw-w-[80px] tw-flex tw-flex-col [justify-content:stretch] tw-bg-[#a9bfd2]"
11
+ ref="target"
12
+ class="tw-top-0 tw-left-0 tw-bottom-0 tw-right-0 tw-w-full tw-h-full tw-absolute tw-flex-shrink-0 tw-bg-white"
13
+ :class="{ animated: !isSwiping, 'vc-table-mobile__item_selected': isSelected }"
14
+ :style="{ left }"
16
15
  >
17
- <div
18
- class="tw-flex tw-grow tw-basis-[1] tw-flex-col tw-justify-center tw-items-center tw-text-white"
19
- :class="[`vc-table-mobile__item-action_${leftSwipeActions[0].variant}`]"
20
- @click.stop="leftSwipeActions[0].clickHandler(item as T)"
21
- >
22
- <VcIcon :icon="leftSwipeActions[0].icon"></VcIcon>
23
- <div class="tw-mt-1 tw-text-lg">
24
- {{ leftSwipeActions[0].title }}
25
- </div>
26
- </div>
27
- </div>
28
-
29
- <div class="tw-flex-shrink-0 tw-w-full">
30
16
  <!-- Mobile item slot content -->
31
17
  <slot></slot>
32
18
  </div>
33
-
34
- <!-- Item actions -->
35
- <div
36
- v-if="rightSwipeActions && rightSwipeActions.length"
37
- class="tw-flex-shrink-0 tw-w-[80px] tw-flex tw-flex-col [justify-content:stretch] tw-bg-[#a9bfd2]"
38
- >
39
- <!-- First available action -->
19
+ <div class="tw-flex tw-justify-between tw-flex-auto">
20
+ <!-- Left swipe actions -->
40
21
  <div
41
- class="tw-flex tw-grow tw-basis-[1] tw-flex-col tw-justify-center tw-items-center tw-text-white"
42
- :class="[`vc-table-mobile__item-action_${rightSwipeActions[0].variant}`]"
43
- @click.stop="rightSwipeActions[0].clickHandler(item as T)"
22
+ v-if="leftSwipeActions && leftSwipeActions.length && direction === 'right'"
23
+ class="tw-flex-shrink-0 tw-flex tw-flex-col [justify-content:stretch] tw-bg-[#a9bfd2]"
24
+ :style="{
25
+ width: actionsWidth,
26
+ }"
44
27
  >
45
- <VcIcon :icon="rightSwipeActions[0].icon"></VcIcon>
46
- <div class="vc-table-mobile__item-action-text">
47
- {{ rightSwipeActions[0].title }}
28
+ <div
29
+ class="tw-flex tw-grow tw-basis-[1] tw-flex-col tw-justify-center tw-items-center tw-text-white"
30
+ :class="[`vc-table-mobile__item-action_${leftSwipeActions[0].type}`]"
31
+ @click.stop="leftSwipeActions[0].clickHandler(item as T)"
32
+ >
33
+ <VcIcon :icon="leftSwipeActions[0].icon" />
34
+ <div class="tw-mt-1 tw-text-lg tw-text-center">
35
+ {{ leftSwipeActions[0].title }}
36
+ </div>
48
37
  </div>
49
38
  </div>
50
-
51
- <!-- Second available action -->
39
+ <!-- Item actions -->
52
40
  <div
53
- v-if="rightSwipeActions.length === 2"
54
- class="tw-flex tw-grow tw-basis-[1] tw-flex-col tw-justify-center tw-items-center tw-text-white"
55
- :class="[`vc-table-mobile__item-action_${rightSwipeActions[1].variant}`]"
56
- @click.stop="rightSwipeActions[1].clickHandler(item as T)"
41
+ v-if="rightSwipeActions && rightSwipeActions.length && direction === 'left'"
42
+ class="tw-flex-shrink-0 tw-flex tw-flex-col [justify-content:stretch] tw-bg-[#a9bfd2] tw-ml-auto"
43
+ :style="{
44
+ width: actionsWidth,
45
+ }"
57
46
  >
58
- <VcIcon :icon="rightSwipeActions[1].icon"></VcIcon>
59
- <div class="tw-mt-1 tw-text-lg">
60
- {{ rightSwipeActions[1].title }}
61
- </div>
62
- </div>
63
-
64
- <!-- Other available actions -->
65
- <template v-if="rightSwipeActions.length > 2">
66
47
  <div
48
+ v-for="(action, index) in rightSwipeActions.slice(0, rightSwipeActions.length > 2 ? 1 : 2)"
49
+ :key="`rightSwipeAction-${index}`"
67
50
  class="tw-flex tw-grow tw-basis-[1] tw-flex-col tw-justify-center tw-items-center tw-text-white"
68
- @click.stop="isActionsPopupVisible = true"
51
+ :class="[`vc-table-mobile__item-action_${action.type}`]"
52
+ @click.stop="action.clickHandler(item as T)"
69
53
  >
70
- <VcIcon icon="fas fa-ellipsis-h"></VcIcon>
71
- <div class="tw-mt-1 tw-text-lg">More</div>
54
+ <VcIcon :icon="action.icon" />
55
+ <div class="tw-mt-1 tw-text-lg tw-text-center">
56
+ {{ action.title }}
57
+ </div>
72
58
  </div>
73
59
 
74
- <!-- Actions popup -->
75
- <teleport
76
- v-if="isActionsPopupVisible"
77
- to="body"
78
- >
60
+ <!-- Other available actions -->
61
+ <template v-if="rightSwipeActions.length > 2">
79
62
  <div
80
- class="tw-absolute tw-left-0 tw-top-0 tw-right-0 tw-bottom-0 tw-bg-[rgba(107,121,135,0.15)] tw-flex tw-items-center tw-justify-center tw-z-[99]"
63
+ class="tw-flex tw-grow tw-basis-[1] tw-flex-col tw-justify-center tw-items-center tw-text-white"
64
+ @click.stop="isActionsPopupVisible = true"
65
+ >
66
+ <VcIcon icon="fas fa-ellipsis-h" />
67
+ <div class="tw-mt-1 tw-text-lg">{{ $t("COMPONENTS.ORGANISMS.VC_TABLE.MORE") }}</div>
68
+ </div>
69
+
70
+ <!-- Actions popup -->
71
+ <teleport
72
+ v-if="isActionsPopupVisible"
73
+ to="body"
81
74
  >
82
75
  <div
83
- class="tw-bg-white tw-rounded-[6px] tw-overflow-hidden tw-p-5 tw-max-w-[80%] tw-w-[350px] tw-border tw-border-solid tw-border-[#eef0f2] tw-box-border tw-shadow-[1px_1px_22px_rgba(126,142,157,0.2)]"
76
+ class="tw-absolute tw-left-0 tw-top-0 tw-right-0 tw-bottom-0 tw-bg-[rgba(107,121,135,0.15)] tw-flex tw-items-center tw-justify-center tw-z-[99]"
84
77
  >
85
- <div class="tw-flex tw-w-full tw-items-center">
86
- <span class="tw-grow tw-text-[#2e3d4e] tw-text-[19px] tw-font-semibold tw-tracking-[-0.01em]">
87
- {{ t("COMPONENTS.ORGANISMS.VC_TABLE.ALL_ACTIONS") }}
88
- </span>
89
- <VcIcon
90
- class="tw-text-[#c2d7e4]"
91
- icon="fas fa-times-circle"
92
- size="xl"
93
- @click="isActionsPopupVisible = false"
94
- ></VcIcon>
95
- </div>
96
-
97
- <div class="tw-flex tw-flex-wrap tw-my-5 tw-justify-between">
98
- <div
99
- v-for="(itemAction, i) in itemActions"
100
- :key="i"
101
- class="tw-flex tw-grow tw-shrink-0 tw-flex-col tw-items-center tw-text-[#319ed4] tw-my-2 tw-box-border tw-p-1 tw-max-w-[80px]"
102
- @click="itemAction.clickHandler(item as T)"
103
- >
78
+ <div
79
+ class="tw-bg-white tw-rounded-[6px] tw-overflow-hidden tw-p-5 tw-max-w-[80%] tw-w-[350px] tw-border tw-border-solid tw-border-[#eef0f2] tw-box-border tw-shadow-[1px_1px_22px_rgba(126,142,157,0.2)]"
80
+ >
81
+ <div class="tw-flex tw-w-full tw-items-center">
82
+ <span class="tw-grow tw-text-[#2e3d4e] tw-text-[19px] tw-font-semibold tw-tracking-[-0.01em]">
83
+ {{ t("COMPONENTS.ORGANISMS.VC_TABLE.ALL_ACTIONS") }}
84
+ </span>
104
85
  <VcIcon
105
- :icon="itemAction.icon"
86
+ class="tw-text-[#c2d7e4]"
87
+ icon="fas fa-times-circle"
106
88
  size="xl"
89
+ @click="isActionsPopupVisible = false"
107
90
  ></VcIcon>
108
- <div class="tw-text-base tw-mt-2 tw-text-center">
109
- {{ itemAction.title }}
91
+ </div>
92
+
93
+ <div class="tw-flex tw-flex-wrap tw-my-5 tw-justify-between">
94
+ <div
95
+ v-for="(itemAction, i) in itemActions"
96
+ :key="i"
97
+ class="tw-flex tw-grow tw-shrink-0 tw-flex-col tw-items-center tw-text-[#319ed4] tw-my-2 tw-box-border tw-p-1 tw-max-w-[80px]"
98
+ @click="itemAction.clickHandler(item as T)"
99
+ >
100
+ <VcIcon
101
+ :icon="itemAction.icon"
102
+ size="xl"
103
+ ></VcIcon>
104
+ <div class="tw-text-base tw-mt-2 tw-text-center">
105
+ {{ itemAction.title }}
106
+ </div>
110
107
  </div>
111
108
  </div>
112
109
  </div>
113
110
  </div>
114
- </div>
115
- </teleport>
116
- </template>
111
+ </teleport>
112
+ </template>
113
+ </div>
117
114
  </div>
118
115
  </div>
119
116
  </template>
120
117
 
121
118
  <script lang="ts" setup generic="T extends TableItem | string">
122
- import { Ref, computed, ref, watch } from "vue";
123
- import { IActionBuilderResult } from "./../../../../../../core/types";
119
+ import { Ref, computed, ref, onMounted, watch } from "vue";
120
+ import { IActionBuilderResult } from "../../../../../../core/types";
124
121
  import { useI18n } from "vue-i18n";
122
+ import { useSwipe } from "@vueuse/core";
123
+ import { vOnClickOutside } from "@vueuse/components";
125
124
 
126
125
  export interface Emits {
127
126
  (event: "swipeStart", id: string): void;
128
127
  (event: "click"): void;
128
+ (event: "select"): void;
129
129
  }
130
130
  export interface TableItem {
131
131
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -135,112 +135,119 @@ export interface TableItem {
135
135
 
136
136
  const props = defineProps<{
137
137
  item: T;
138
- actionBuilder?: (item: T) => IActionBuilderResult[];
138
+ actionBuilder?: (item: T) => IActionBuilderResult[] | undefined;
139
139
  swipingItem?: string;
140
+ isSelected?: boolean;
140
141
  }>();
141
142
 
142
143
  const emit = defineEmits<Emits>();
143
144
  const { t } = useI18n({ useScope: "global" });
144
- const offsetX = ref(0);
145
- const startX = ref(0);
146
- const startY = ref(0);
147
- const startOffsetX = ref(0);
148
- const isMoving = ref(false);
149
- const threshold = 10;
150
- const maxWidth = 80;
145
+
151
146
  const isActionsPopupVisible = ref(false);
152
- const itemActions: Ref<IActionBuilderResult<T>[]> = ref([]);
147
+ const itemActions: Ref<IActionBuilderResult<T>[] | undefined> = ref([]);
148
+ const target = ref<HTMLElement | null>(null);
149
+ const container = ref<HTMLElement | null>(null);
150
+ const containerWidth = computed(() => container.value?.offsetWidth);
151
+ const left = ref("0");
153
152
 
154
- watch(
155
- () => props.swipingItem,
156
- (newVal) => {
157
- if (typeof props.item !== "string" && newVal !== props.item.id) {
158
- handleOffset();
153
+ const actionsWidth = ref("0");
154
+
155
+ const { isSwiping, lengthX } = useSwipe(target, {
156
+ threshold: 0,
157
+ onSwipeStart() {
158
+ getActions();
159
+ if (typeof props.item !== "string") {
160
+ emit("swipeStart", props.item.id);
161
+ }
162
+ if (containerWidth.value) {
163
+ reset();
159
164
  }
160
165
  },
161
- );
166
+ onSwipe() {
167
+ if (containerWidth.value) {
168
+ if (lengthX.value < 0 && leftSwipeActions.value && leftSwipeActions.value.length) {
169
+ left.value = `${Math.abs(lengthX.value)}px`;
170
+ } else if (lengthX.value > 0 && rightSwipeActions.value && rightSwipeActions.value.length) {
171
+ left.value = `${-lengthX.value}px`;
172
+ }
173
+
174
+ actionsWidth.value = `${Math.abs(lengthX.value)}px`;
175
+ }
176
+ },
177
+ onSwipeEnd() {
178
+ if (containerWidth.value && Math.abs(lengthX.value) / containerWidth.value >= 0.1) {
179
+ if (lengthX.value < 0 && leftSwipeActions.value && leftSwipeActions.value.length) {
180
+ left.value = "80px";
181
+ } else if (lengthX.value > 0 && rightSwipeActions.value && rightSwipeActions.value.length) {
182
+ left.value = "-80px";
183
+ }
184
+
185
+ actionsWidth.value = "80px";
186
+ } else {
187
+ reset();
188
+ }
189
+ },
190
+ });
162
191
 
163
192
  const rightSwipeActions = computed(
164
193
  () =>
165
194
  itemActions.value &&
166
195
  itemActions.value.length &&
167
- itemActions.value.filter((actions: IActionBuilderResult) => !actions.leftActions),
196
+ itemActions.value.filter((actions: IActionBuilderResult) => actions.position === "right"),
168
197
  );
169
198
  const leftSwipeActions = computed(
170
199
  () =>
171
200
  itemActions.value &&
172
201
  itemActions.value.length &&
173
- itemActions.value.filter((actions: IActionBuilderResult) => actions.leftActions),
202
+ itemActions.value.filter((actions: IActionBuilderResult) => actions.position === "left"),
174
203
  );
175
204
 
176
- function handleOffset() {
177
- if (itemActions.value.some((action: IActionBuilderResult) => action.leftActions)) {
178
- offsetX.value = -maxWidth;
179
- startOffsetX.value = offsetX.value;
180
- } else {
181
- offsetX.value = 0;
182
- startOffsetX.value = 0;
183
- }
184
- }
205
+ watch(
206
+ () => props.swipingItem,
207
+ (newVal) => {
208
+ if (typeof props.item !== "string" && newVal !== props.item.id) {
209
+ left.value = "0";
210
+ actionsWidth.value = "0";
211
+ }
212
+ },
213
+ );
185
214
 
186
- async function touchStart(e: TouchEvent) {
187
- startX.value = e.touches[0].clientX;
188
- startY.value = e.touches[0].clientY;
189
- startOffsetX.value = offsetX.value;
190
- isMoving.value = true;
215
+ onMounted(() => {
216
+ adjustHeight();
217
+ });
191
218
 
192
- if (!itemActions.value.length) {
193
- if (typeof props.actionBuilder === "function") {
194
- itemActions.value = props.actionBuilder(props.item);
219
+ function reset() {
220
+ left.value = "0";
221
+ actionsWidth.value = "0";
222
+ }
195
223
 
196
- handleOffset();
197
- }
224
+ function adjustHeight() {
225
+ if (container.value && target.value) {
226
+ container.value.style.height = target.value.scrollHeight + "px";
198
227
  }
199
228
  }
200
229
 
201
- function touchMove(e: TouchEvent) {
202
- if (typeof props.item !== "string") emit("swipeStart", props.item.id);
203
- if (itemActions.value && itemActions.value.length) {
204
- const deltaX = e.touches[0].clientX - startX.value;
205
- const deltaY = e.touches[0].clientY - startY.value;
230
+ const direction = computed(() => {
231
+ if (lengthX.value < 0) {
232
+ return "right";
233
+ }
234
+ return "left";
235
+ });
206
236
 
207
- if (
208
- Math.abs(deltaX) > threshold &&
209
- (rightSwipeActions.value && rightSwipeActions.value.length
210
- ? leftSwipeActions.value && leftSwipeActions.value.length
211
- ? Math.abs(startOffsetX.value + deltaX) <= maxWidth * 2
212
- : Math.abs(startOffsetX.value + deltaX) <= maxWidth
213
- : Math.abs(startOffsetX.value + deltaX) <= maxWidth) &&
214
- startOffsetX.value + deltaX < 0
215
- ) {
216
- if (Math.abs(deltaY) < threshold * 2) {
217
- e.preventDefault();
218
- }
219
- offsetX.value = startOffsetX.value + deltaX;
237
+ function getActions() {
238
+ if (!(itemActions.value && itemActions.value.length)) {
239
+ if (props.actionBuilder && typeof props.actionBuilder === "function") {
240
+ itemActions.value = props.actionBuilder(props.item);
220
241
  }
221
242
  }
222
243
  }
223
244
 
224
- function touchEnd() {
225
- const absoluteOffsetX = Math.abs(offsetX.value);
226
- if (absoluteOffsetX < maxWidth) {
227
- offsetX.value = absoluteOffsetX < maxWidth / 2 ? 0 : -maxWidth;
228
- } else {
229
- offsetX.value = absoluteOffsetX <= maxWidth * 2 - threshold * 2 ? -maxWidth : -maxWidth * 2;
230
- }
231
-
232
- isMoving.value = false;
245
+ function handleHold() {
246
+ emit("select");
233
247
  }
234
248
 
235
- function touchCancel() {
236
- const absoluteOffsetX = Math.abs(offsetX.value);
237
- if (absoluteOffsetX < maxWidth) {
238
- offsetX.value = absoluteOffsetX < maxWidth / 2 ? 0 : -maxWidth;
239
- } else {
240
- offsetX.value = absoluteOffsetX <= maxWidth * 2 - threshold * 2 ? -maxWidth : -maxWidth * 2;
241
- }
242
-
243
- isMoving.value = false;
249
+ function handleClick() {
250
+ emit("click");
244
251
  }
245
252
  </script>
246
253
 
@@ -255,5 +262,9 @@ function touchCancel() {
255
262
  @apply tw-bg-[#ff4a4a];
256
263
  }
257
264
  }
265
+
266
+ &_selected {
267
+ @apply tw-bg-[#dfeef9] #{!important};
268
+ }
258
269
  }
259
270
  </style>
@@ -64,7 +64,7 @@
64
64
  v-if="items && items.length"
65
65
  ref="scrollContainer"
66
66
  :no-padding="true"
67
- class="tw-grow tw-basis-0"
67
+ class="tw-grow tw-basis-0 tw-relative"
68
68
  :use-ptr="pullToReload"
69
69
  @scroll:ptr="$emit('scroll:ptr')"
70
70
  >
@@ -77,8 +77,10 @@
77
77
  :item="item"
78
78
  :action-builder="itemActionBuilder"
79
79
  :swiping-item="mobileSwipeItem"
80
+ :is-selected="isSelected(item)"
80
81
  @click="$emit('itemClick', item)"
81
82
  @swipe-start="handleSwipe"
83
+ @select="rowCheckbox(item)"
82
84
  >
83
85
  <slot
84
86
  name="mobile-item"
@@ -118,7 +120,7 @@
118
120
  </div>
119
121
  </th>
120
122
  <th
121
- v-if="itemActionBuilder"
123
+ v-if="enableItemActions && itemActionBuilder"
122
124
  class="tw-h-[42px] tw-w-[21px] tw-max-w-[21px] tw-min-w-[21px] tw-bg-[#f9f9f9] tw-m-w-[70px] !tw-border-0 tw-shadow-[inset_0px_1px_0px_#eaedf3,_inset_0px_-1px_0px_#eaedf3] tw-box-border tw-sticky tw-top-0 tw-select-none tw-z-[1]"
123
125
  >
124
126
  <div class="tw-w-3 tw-top-0 tw-bottom-0 tw-absolute tw-right-0 tw-flex tw-justify-end">
@@ -262,7 +264,7 @@
262
264
  <div class="tw-w-px tw-top-0 tw-bottom-0 tw-absolute tw-right-0 tw-bg-[#e5e7eb]"></div>
263
265
  </td>
264
266
  <td
265
- v-if="itemActionBuilder && typeof item === 'object'"
267
+ v-if="enableItemActions && itemActionBuilder && typeof item === 'object'"
266
268
  class="tw-box-border tw-overflow-visible tw-w-[21px] tw-max-w-[21px] tw-min-w-[21px] tw-relative"
267
269
  @click.stop
268
270
  >
@@ -298,7 +300,7 @@
298
300
  :key="i"
299
301
  :class="[
300
302
  'tw-flex tw-flex-row tw-items-center tw-text-[#319ed4] tw-cursor-pointer',
301
- `vc-table__body-actions-item_${itemAction.variant}`,
303
+ `vc-table__body-actions-item_${itemAction.type}`,
302
304
  ]"
303
305
  @click.stop="itemAction.clickHandler(item)"
304
306
  >
@@ -477,7 +479,7 @@ const props = withDefaults(
477
479
  defineProps<{
478
480
  columns: ITableColumns[];
479
481
  items: T[];
480
- itemActionBuilder?: (item: T) => IActionBuilderResult[];
482
+ itemActionBuilder?: (item: T) => IActionBuilderResult[] | undefined;
481
483
  sort?: string;
482
484
  multiselect?: boolean;
483
485
  expanded?: boolean;
@@ -500,6 +502,7 @@ const props = withDefaults(
500
502
  reorderableRows?: boolean;
501
503
  stateKey: string;
502
504
  selectAll?: boolean;
505
+ enableItemActions?: boolean;
503
506
  }>(),
504
507
  {
505
508
  items: () => [],
@@ -788,12 +791,14 @@ const arrowStyle = computed(() => {
788
791
  });
789
792
 
790
793
  async function calculateActions(items: T[]) {
791
- if (typeof props.itemActionBuilder === "function") {
792
- const populatedItems = [];
794
+ if (props.enableItemActions && typeof props.itemActionBuilder === "function") {
795
+ const populatedItems: IActionBuilderResult[][] = [];
793
796
  for (let index = 0; index < items.length; index++) {
794
797
  if (typeof items[index] === "object") {
795
798
  const elementWithActions = await props.itemActionBuilder(items[index]);
796
- populatedItems.push(elementWithActions);
799
+ if (elementWithActions) {
800
+ populatedItems.push(elementWithActions);
801
+ }
797
802
  }
798
803
  }
799
804
  itemActions.value = populatedItems;
@@ -1,3 +0,0 @@
1
- import * as en from "./en.json";
2
- export { en };
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../shared/modules/assets/locales/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,WAAW,CAAC;AAChC,OAAO,EAAE,EAAE,EAAE,CAAC"}
@@ -1,3 +0,0 @@
1
- import * as en from "./en.json";
2
- export { en };
3
- //# sourceMappingURL=index.d.ts.map