@vc-shell/framework 1.2.2 → 1.2.3-beta.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/core/composables/index.ts +2 -0
- package/core/composables/useAssets/index.ts +72 -28
- package/core/composables/useAsync/index.ts +4 -1
- package/core/composables/useBladeRegistry/index.ts +6 -5
- package/core/composables/useBreadcrumbs/index.ts +4 -1
- package/core/composables/useErrorHandler/index.ts +4 -1
- package/core/composables/useFunctions/debounce.ts +0 -1
- package/core/composables/useFunctions/delay.ts +0 -1
- package/core/composables/useFunctions/index.ts +0 -1
- package/core/composables/useFunctions/once.ts +0 -1
- package/core/composables/useFunctions/sleep.ts +0 -1
- package/core/composables/useFunctions/throttle.ts +0 -1
- package/core/composables/useGlobalSearch/index.ts +3 -3
- package/core/composables/useMenuService/index.ts +5 -2
- package/core/composables/useNotifications/index.ts +5 -2
- package/core/composables/useTheme/index.ts +4 -1
- package/core/composables/useUser/index.ts +189 -20
- package/core/composables/useWidgets/index.ts +5 -2
- package/core/constants/defaults.ts +76 -0
- package/core/constants/index.ts +2 -0
- package/core/constants/ui.ts +68 -0
- package/core/interceptors/index.ts +5 -2
- package/core/plugins/ai-agent/README.md +336 -0
- package/core/plugins/ai-agent/components/VcAiAgentPanel.vue +125 -0
- package/core/plugins/ai-agent/components/_internal/VcAiAgentHeader.vue +182 -0
- package/core/plugins/ai-agent/components/_internal/VcAiAgentIframe.vue +77 -0
- package/core/plugins/ai-agent/components/index.ts +1 -0
- package/core/plugins/ai-agent/composables/index.ts +4 -0
- package/core/plugins/ai-agent/composables/useAiAgent.ts +231 -0
- package/core/plugins/ai-agent/composables/useAiAgentContext.ts +280 -0
- package/core/plugins/ai-agent/constants.ts +89 -0
- package/core/plugins/ai-agent/index.ts +91 -0
- package/core/plugins/ai-agent/services/ai-agent-service.ts +598 -0
- package/core/plugins/ai-agent/types.ts +310 -0
- package/core/plugins/modularity/index.ts +8 -6
- package/core/plugins/modularity/loader.ts +36 -33
- package/core/plugins/signalR/index.ts +6 -3
- package/core/services/app-bar-menu-service.ts +4 -1
- package/core/services/dashboard-service.ts +4 -1
- package/core/services/index.ts +2 -0
- package/core/services/menu-service.ts +4 -1
- package/core/services/settings-menu-service.ts +4 -1
- package/core/services/toolbar-service.ts +18 -3
- package/core/services/widget-service.ts +7 -4
- package/core/types/index.ts +3 -0
- package/core/types/services.ts +194 -0
- package/core/utilities/errorTypes.ts +126 -0
- package/core/utilities/index.ts +2 -0
- package/core/utilities/logger.ts +120 -0
- package/dist/core/composables/useAssets/index.d.ts.map +1 -1
- package/dist/core/composables/useAsync/index.d.ts.map +1 -1
- package/dist/core/composables/useBladeRegistry/index.d.ts.map +1 -1
- package/dist/core/composables/useBreadcrumbs/index.d.ts.map +1 -1
- package/dist/core/composables/useErrorHandler/index.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/debounce.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/delay.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/index.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/once.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/sleep.d.ts.map +1 -1
- package/dist/core/composables/useFunctions/throttle.d.ts.map +1 -1
- package/dist/core/composables/useGlobalSearch/index.d.ts.map +1 -1
- package/dist/core/composables/useMenuService/index.d.ts.map +1 -1
- package/dist/core/composables/useNotifications/index.d.ts.map +1 -1
- package/dist/core/composables/useTheme/index.d.ts.map +1 -1
- package/dist/core/composables/useUser/index.d.ts +8 -0
- package/dist/core/composables/useUser/index.d.ts.map +1 -1
- package/dist/core/composables/useWidgets/index.d.ts.map +1 -1
- package/dist/core/constants/defaults.d.ts +63 -0
- package/dist/core/constants/defaults.d.ts.map +1 -0
- package/dist/core/constants/index.d.ts +2 -0
- package/dist/core/constants/index.d.ts.map +1 -1
- package/dist/core/constants/ui.d.ts +50 -0
- package/dist/core/constants/ui.d.ts.map +1 -0
- package/dist/core/interceptors/index.d.ts.map +1 -1
- package/dist/core/plugins/ai-agent/components/VcAiAgentPanel.vue.d.ts +3 -0
- package/dist/core/plugins/ai-agent/components/VcAiAgentPanel.vue.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentHeader.vue.d.ts +15 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentHeader.vue.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentIframe.vue.d.ts +10 -0
- package/dist/core/plugins/ai-agent/components/_internal/VcAiAgentIframe.vue.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/components/index.d.ts +2 -0
- package/dist/core/plugins/ai-agent/components/index.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/composables/index.d.ts +4 -0
- package/dist/core/plugins/ai-agent/composables/index.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgent.d.ts +95 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgent.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgentContext.d.ts +55 -0
- package/dist/core/plugins/ai-agent/composables/useAiAgentContext.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/constants.d.ts +47 -0
- package/dist/core/plugins/ai-agent/constants.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/index.d.ts +48 -0
- package/dist/core/plugins/ai-agent/index.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/services/ai-agent-service.d.ts +45 -0
- package/dist/core/plugins/ai-agent/services/ai-agent-service.d.ts.map +1 -0
- package/dist/core/plugins/ai-agent/types.d.ts +258 -0
- package/dist/core/plugins/ai-agent/types.d.ts.map +1 -0
- package/dist/core/plugins/modularity/index.d.ts.map +1 -1
- package/dist/core/plugins/modularity/loader.d.ts.map +1 -1
- package/dist/core/plugins/signalR/index.d.ts.map +1 -1
- package/dist/core/services/app-bar-menu-service.d.ts.map +1 -1
- package/dist/core/services/dashboard-service.d.ts.map +1 -1
- package/dist/core/services/menu-service.d.ts.map +1 -1
- package/dist/core/services/settings-menu-service.d.ts.map +1 -1
- package/dist/core/services/toolbar-service.d.ts.map +1 -1
- package/dist/core/services/widget-service.d.ts.map +1 -1
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/services.d.ts +169 -0
- package/dist/core/types/services.d.ts.map +1 -0
- package/dist/core/utilities/errorTypes.d.ts +61 -0
- package/dist/core/utilities/errorTypes.d.ts.map +1 -0
- package/dist/core/utilities/index.d.ts +2 -0
- package/dist/core/utilities/index.d.ts.map +1 -1
- package/dist/core/utilities/logger.d.ts +259 -0
- package/dist/core/utilities/logger.d.ts.map +1 -0
- package/dist/framework.js +9623 -8417
- package/dist/index.css +1 -1
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/injection-keys.d.ts +21 -6
- package/dist/injection-keys.d.ts.map +1 -1
- package/dist/shared/components/app-switcher/composables/useAppSwitcher/index.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/index.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.d.ts.map +1 -1
- package/dist/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.d.ts.map +1 -1
- package/dist/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.d.ts.map +1 -1
- package/dist/shared/components/draggable-dashboard/composables/useLayoutPersistence.d.ts.map +1 -1
- package/dist/shared/components/notifications/composables/useContainer/index.d.ts.map +1 -1
- package/dist/shared/components/notifications/composables/useInstance/index.d.ts.map +1 -1
- package/dist/shared/components/notifications/core/notification.d.ts.map +1 -1
- package/dist/shared/components/popup-handler/components/vc-popup-container/vc-popup-container.vue.d.ts.map +1 -1
- package/dist/shared/components/sign-in/useExternalProvider.d.ts.map +1 -1
- package/dist/shared/composables/index.d.ts +1 -0
- package/dist/shared/composables/index.d.ts.map +1 -1
- package/dist/shared/composables/useExternalWidgets.d.ts.map +1 -1
- package/dist/shared/composables/useMenuExpanded.d.ts.map +1 -1
- package/dist/shared/composables/useTableSelection.d.ts +57 -0
- package/dist/shared/composables/useTableSelection.d.ts.map +1 -0
- package/dist/shared/composables/useTableSort.d.ts.map +1 -1
- package/dist/shared/modules/assets-manager/components/assets-manager/assets-manager.vue.d.ts.map +1 -1
- package/dist/shared/pages/LoginPage/components/login/Login.vue.d.ts.map +1 -1
- package/dist/shared/utilities/colorUtils.d.ts +0 -6
- package/dist/shared/utilities/colorUtils.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/ui/components/atoms/vc-banner/vc-banner.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts +0 -15
- package/dist/ui/components/atoms/vc-button/vc-button.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-container/vc-container.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-icon/vc-lucide-icon.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-image/vc-image.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-link/vc-link.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-loading/vc-loading.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-status/vc-status.vue.d.ts +0 -5
- package/dist/ui/components/atoms/vc-status/vc-status.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-tooltip/vc-tooltip.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-video/vc-video.vue.d.ts.map +1 -1
- package/dist/ui/components/atoms/vc-widget/vc-widget.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-input/vc-input.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-pagination/vc-pagination.vue.d.ts.map +1 -1
- package/dist/ui/components/molecules/vc-toast/vc-toast.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-app/vc-app.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-blade/vc-blade.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-login-form/vc-login-form.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableActions.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableColumnResize.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableRowReorder.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableSelection.d.ts.map +1 -1
- package/dist/ui/components/organisms/vc-table/composables/useTableState.d.ts.map +1 -1
- package/dist/{vendor-lodash-es-BqkGj3Jl.js → vendor-lodash-es-SgOIjJF8.js} +2 -0
- package/package.json +5 -5
- package/shared/components/app-switcher/composables/useAppSwitcher/index.ts +4 -1
- package/shared/components/blade-navigation/components/vc-blade-navigation/vc-blade-navigation.vue +67 -4
- package/shared/components/blade-navigation/composables/useBladeNavigation/index.ts +13 -10
- package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeActions.ts +7 -4
- package/shared/components/blade-navigation/composables/useBladeNavigation/internal/bladeRouteResolver.ts +4 -1
- package/shared/components/blade-navigation/composables/useBladeNavigation/internal/routerUtils.ts +4 -1
- package/shared/components/change-password/change-password.vue +1 -1
- package/shared/components/draggable-dashboard/composables/useDashboardDragAndDrop.ts +14 -5
- package/shared/components/draggable-dashboard/composables/useLayoutPersistence.ts +5 -2
- package/shared/components/index.ts +2 -0
- package/shared/components/notifications/composables/useContainer/index.ts +8 -6
- package/shared/components/notifications/composables/useInstance/index.ts +4 -1
- package/shared/components/notifications/core/notification.ts +10 -7
- package/shared/components/popup-handler/components/vc-popup-container/vc-popup-container.vue +20 -1
- package/shared/components/sign-in/useExternalProvider.ts +6 -4
- package/shared/composables/index.ts +1 -0
- package/shared/composables/useExternalWidgets.ts +7 -4
- package/shared/composables/useMenuExpanded.ts +15 -1
- package/shared/composables/useTableSelection.ts +151 -0
- package/shared/composables/useTableSort.ts +4 -4
- package/shared/modules/assets-manager/components/assets-manager/assets-manager.vue +6 -3
- package/shared/pages/LoginPage/components/login/Login.vue +4 -1
- package/shared/utilities/colorUtils.ts +5 -12
- package/ui/components/atoms/vc-banner/vc-banner.vue +4 -1
- package/ui/components/atoms/vc-button/vc-button.vue +2 -25
- package/ui/components/atoms/vc-container/vc-container.vue +12 -3
- package/ui/components/atoms/vc-icon/vc-icon.vue +0 -10
- package/ui/components/atoms/vc-icon/vc-lucide-icon.vue +5 -2
- package/ui/components/atoms/vc-image/vc-image.vue +4 -1
- package/ui/components/atoms/vc-link/vc-link.vue +59 -54
- package/ui/components/atoms/vc-loading/vc-loading.vue +4 -0
- package/ui/components/atoms/vc-status/vc-status.vue +0 -5
- package/ui/components/atoms/vc-status-icon/vc-status-icon.vue +4 -4
- package/ui/components/atoms/vc-tooltip/vc-tooltip.vue +8 -1
- package/ui/components/atoms/vc-video/vc-video.vue +4 -2
- package/ui/components/atoms/vc-widget/vc-widget.vue +4 -1
- package/ui/components/molecules/vc-breadcrumbs/vc-breadcrumbs.vue +7 -2
- package/ui/components/molecules/vc-input/vc-input.vue +0 -1
- package/ui/components/molecules/vc-pagination/vc-pagination.vue +6 -1
- package/ui/components/molecules/vc-rating/vc-rating.vue +1 -1
- package/ui/components/molecules/vc-textarea/vc-textarea.vue +1 -1
- package/ui/components/molecules/vc-toast/vc-toast.vue +11 -1
- package/ui/components/organisms/vc-app/vc-app.vue +22 -3
- package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/_internal/vc-blade-toolbar-buttons/_internal/vc-blade-toolbar-button/vc-blade-toolbar-button.vue +4 -1
- package/ui/components/organisms/vc-blade/_internal/vc-blade-toolbar/vc-blade-toolbar.vue +14 -14
- package/ui/components/organisms/vc-blade/vc-blade.vue +3 -1
- package/ui/components/organisms/vc-login-form/vc-login-form.vue +3 -1
- package/ui/components/organisms/vc-table/_internal/vc-table-cell/vc-table-cell.vue +34 -2
- package/ui/components/organisms/vc-table/composables/useTableActions.ts +7 -10
- package/ui/components/organisms/vc-table/composables/useTableColumnResize.ts +4 -1
- package/ui/components/organisms/vc-table/composables/useTableRowReorder.ts +5 -2
- package/ui/components/organisms/vc-table/composables/useTableSelection.ts +26 -18
- package/ui/components/organisms/vc-table/composables/useTableState.ts +4 -1
- package/core/services/global-search-service.ts +0 -36
- package/dist/core/services/global-search-service.d.ts +0 -10
- package/dist/core/services/global-search-service.d.ts.map +0 -1
|
@@ -25,10 +25,10 @@ import { useLocalStorage } from "@vueuse/core";
|
|
|
25
25
|
import { usePermissions, useToolbar } from "../../../../../../core/composables";
|
|
26
26
|
import { IBladeToolbar } from "../../../../../../core/types";
|
|
27
27
|
import VcBladeToolbarButtons from "./_internal/vc-blade-toolbar-buttons/vc-blade-toolbar-buttons.vue";
|
|
28
|
-
import { BladeInstance } from "../../../../../../injection-keys";
|
|
29
28
|
import { FALLBACK_BLADE_ID } from "../../../../../../core/constants";
|
|
30
29
|
import { IBladeInstance } from "../../../../../../shared/components/blade-navigation/types";
|
|
31
30
|
import { IToolbarItem } from "../../../../../../core/services";
|
|
31
|
+
import { useBlade } from "../../../../../../core/composables";
|
|
32
32
|
|
|
33
33
|
export interface Props {
|
|
34
34
|
items: IBladeToolbar[];
|
|
@@ -41,21 +41,17 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
41
41
|
const slots = useSlots();
|
|
42
42
|
const isExpanded = useLocalStorage("VC_BLADE_TOOLBAR_IS_EXPANDED", true);
|
|
43
43
|
const { hasAccess } = usePermissions();
|
|
44
|
-
const {
|
|
45
|
-
|
|
44
|
+
const {
|
|
45
|
+
registerToolbarItem,
|
|
46
|
+
unregisterToolbarItem,
|
|
47
|
+
getToolbarItems,
|
|
48
|
+
clearBladeToolbarItems,
|
|
49
|
+
updateToolbarItem,
|
|
50
|
+
registeredToolbarItems,
|
|
51
|
+
} = useToolbar();
|
|
46
52
|
|
|
47
53
|
// Get the ID of the current blade
|
|
48
|
-
const blade =
|
|
49
|
-
BladeInstance,
|
|
50
|
-
computed(() => ({
|
|
51
|
-
id: FALLBACK_BLADE_ID,
|
|
52
|
-
expandable: false,
|
|
53
|
-
maximized: false,
|
|
54
|
-
error: undefined,
|
|
55
|
-
navigation: undefined,
|
|
56
|
-
breadcrumbs: undefined,
|
|
57
|
-
})),
|
|
58
|
-
);
|
|
54
|
+
const blade = useBlade();
|
|
59
55
|
|
|
60
56
|
const bladeId = computed(() => (blade.value?.id ?? FALLBACK_BLADE_ID).toLowerCase());
|
|
61
57
|
|
|
@@ -126,6 +122,10 @@ function clearToolbarItems(): void {
|
|
|
126
122
|
|
|
127
123
|
// Filter visible items from service
|
|
128
124
|
const visibleItems = computed(() => {
|
|
125
|
+
// Access registeredToolbarItems.length to create reactive dependency
|
|
126
|
+
// This ensures computed recalculates when new items are registered
|
|
127
|
+
void registeredToolbarItems.length;
|
|
128
|
+
|
|
129
129
|
return getToolbarItems()
|
|
130
130
|
.filter(
|
|
131
131
|
(item) =>
|
|
@@ -288,8 +288,10 @@ const openErrorDetails = () => {
|
|
|
288
288
|
}
|
|
289
289
|
|
|
290
290
|
.vc-blade {
|
|
291
|
-
@apply tw-relative tw-flex tw-shrink-0 tw-flex-col tw-overflow-hidden
|
|
291
|
+
@apply tw-relative tw-flex tw-shrink-0 tw-flex-col tw-overflow-hidden;
|
|
292
292
|
@apply tw-bg-[color:var(--blade-background-color)] tw-border tw-border-solid tw-border-[--blade-border-color];
|
|
293
|
+
// Use shared transition timing for synchronized animations with AI panel
|
|
294
|
+
transition: width var(--app-panel-transition-duration, 0.3s) var(--app-panel-transition-timing, cubic-bezier(0.4, 0, 0.2, 1));
|
|
293
295
|
|
|
294
296
|
&__back-button {
|
|
295
297
|
@apply tw-mr-[14px];
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
<script lang="ts" setup>
|
|
25
25
|
import { computed } from "vue";
|
|
26
26
|
import { useRouter } from "vue-router";
|
|
27
|
+
import { createLogger } from "../../../../core/utilities";
|
|
27
28
|
|
|
28
29
|
export interface Props {
|
|
29
30
|
logo?: string;
|
|
@@ -57,7 +58,8 @@ const logoImageHandler = computed(() => {
|
|
|
57
58
|
|
|
58
59
|
const version = router.currentRoute.value.meta?.appVersion;
|
|
59
60
|
|
|
60
|
-
|
|
61
|
+
const logger = createLogger("vc-login-form");
|
|
62
|
+
logger.debug("Init vc-login-form");
|
|
61
63
|
</script>
|
|
62
64
|
|
|
63
65
|
<style lang="scss">
|
|
@@ -290,6 +290,38 @@ import { Field } from "vee-validate";
|
|
|
290
290
|
import type { TableItem } from "../../types";
|
|
291
291
|
import { ITableColumns } from "../../../../../../core/types";
|
|
292
292
|
|
|
293
|
+
// Cache for sanitized HTML to avoid repeated DOMPurify calls across table cells
|
|
294
|
+
const sanitizedHtmlCache = new Map<string, string>();
|
|
295
|
+
const MAX_CACHE_SIZE = 500;
|
|
296
|
+
|
|
297
|
+
function getSanitizedHtml(html: string): string {
|
|
298
|
+
if (sanitizedHtmlCache.has(html)) {
|
|
299
|
+
return sanitizedHtmlCache.get(html)!;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
const sanitized = DOMPurify.default.sanitize(html, {
|
|
303
|
+
ALLOWED_TAGS: [
|
|
304
|
+
"p", "br", "strong", "em", "u", "s", "h1", "h2", "h3", "h4", "h5", "h6",
|
|
305
|
+
"ul", "ol", "li", "blockquote", "pre", "code", "a", "img", "table",
|
|
306
|
+
"thead", "tbody", "tr", "th", "td", "hr", "div", "span",
|
|
307
|
+
],
|
|
308
|
+
ALLOWED_ATTR: ["href", "src", "alt", "title", "class", "id", "colspan", "rowspan", "align", "valign"],
|
|
309
|
+
FORBID_TAGS: ["script", "object", "embed", "form", "input"],
|
|
310
|
+
FORBID_ATTR: ["onerror", "onload", "onclick", "onmouseover", "onfocus", "onblur", "style"],
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// Limit cache size to prevent memory leaks
|
|
314
|
+
if (sanitizedHtmlCache.size >= MAX_CACHE_SIZE) {
|
|
315
|
+
const firstKey = sanitizedHtmlCache.keys().next().value;
|
|
316
|
+
if (firstKey !== undefined) {
|
|
317
|
+
sanitizedHtmlCache.delete(firstKey);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
sanitizedHtmlCache.set(html, sanitized);
|
|
322
|
+
return sanitized;
|
|
323
|
+
}
|
|
324
|
+
|
|
293
325
|
export interface Props {
|
|
294
326
|
cell: ITableColumns;
|
|
295
327
|
item: string | TableItem;
|
|
@@ -313,8 +345,8 @@ const value = computed((): any => _.get(props.item, props.cell.field || props.ce
|
|
|
313
345
|
const isEditable = computed(() => props.cell.editable && props.editing);
|
|
314
346
|
|
|
315
347
|
const sanitizedHtml = computed(() => {
|
|
316
|
-
if (props.cell.type === "html") {
|
|
317
|
-
return
|
|
348
|
+
if (props.cell.type === "html" && value.value) {
|
|
349
|
+
return getSanitizedHtml(String(value.value));
|
|
318
350
|
}
|
|
319
351
|
return "";
|
|
320
352
|
});
|
|
@@ -20,16 +20,13 @@ export function useTableActions<T extends TableItem | string>(options: UseTableA
|
|
|
20
20
|
const builder = unref(itemActionBuilder);
|
|
21
21
|
|
|
22
22
|
if (unref(enableItemActions) && typeof builder === "function") {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
itemActions.value = populatedItems;
|
|
23
|
+
// Use Promise.all for parallel execution instead of sequential awaits
|
|
24
|
+
const actionPromises = items
|
|
25
|
+
.filter((item) => typeof item === "object")
|
|
26
|
+
.map((item) => builder(item));
|
|
27
|
+
|
|
28
|
+
const results = await Promise.all(actionPromises);
|
|
29
|
+
itemActions.value = results.filter((result): result is IActionBuilderResult<T>[] => !!result);
|
|
33
30
|
} else {
|
|
34
31
|
itemActions.value = [];
|
|
35
32
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { ref, Ref } from "vue";
|
|
2
2
|
import { TableColPartial } from "../types";
|
|
3
|
+
import { createLogger } from "../../../../../core/utilities";
|
|
4
|
+
|
|
5
|
+
const logger = createLogger("vc-table-column-resize");
|
|
3
6
|
|
|
4
7
|
export function useTableColumnResize(
|
|
5
8
|
internalColumns: Ref<TableColPartial[]>,
|
|
@@ -35,7 +38,7 @@ export function useTableColumnResize(
|
|
|
35
38
|
e.stopImmediatePropagation();
|
|
36
39
|
|
|
37
40
|
if (!item.id) {
|
|
38
|
-
|
|
41
|
+
logger.warn("Column has no id, cannot resize:", item);
|
|
39
42
|
return;
|
|
40
43
|
}
|
|
41
44
|
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { computed, ref, Ref } from "vue";
|
|
2
2
|
import { TableItem } from "../types";
|
|
3
|
+
import { createLogger } from "../../../../../core/utilities";
|
|
4
|
+
|
|
5
|
+
const logger = createLogger("vc-table-row-reorder");
|
|
3
6
|
|
|
4
7
|
export function useTableRowReorder<T extends TableItem | string>(
|
|
5
8
|
items: Ref<T[]>,
|
|
@@ -27,7 +30,7 @@ export function useTableRowReorder<T extends TableItem | string>(
|
|
|
27
30
|
function onRowMouseDown(event: MouseEvent) {
|
|
28
31
|
if (event.currentTarget instanceof HTMLElement) {
|
|
29
32
|
const row = event.currentTarget;
|
|
30
|
-
|
|
33
|
+
logger.debug("Row mousedown event", row);
|
|
31
34
|
const rowRect = row.getBoundingClientRect();
|
|
32
35
|
|
|
33
36
|
dragOffset.value = {
|
|
@@ -54,7 +57,7 @@ export function useTableRowReorder<T extends TableItem | string>(
|
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
function onRowDragStart(event: DragEvent, item: T) {
|
|
57
|
-
|
|
60
|
+
logger.debug("Row drag start", { item });
|
|
58
61
|
rowDragged.value = true;
|
|
59
62
|
const index = internalItems.value.indexOf(item);
|
|
60
63
|
draggedRow.value = index;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { computed, ref, Ref, watch } from "vue";
|
|
2
2
|
import { TableItem } from "../types";
|
|
3
|
-
import * as _ from "lodash-es";
|
|
4
3
|
|
|
5
4
|
type TableItemType = TableItem | string;
|
|
6
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Gets a unique identifier for a table item
|
|
8
|
+
*/
|
|
9
|
+
function getItemId(item: TableItemType): string {
|
|
10
|
+
if (typeof item === "string") return item;
|
|
11
|
+
return (item as TableItem).id ?? JSON.stringify(item);
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
export interface UseTableSelectionOptions<T extends TableItemType> {
|
|
8
15
|
items: Ref<T[]>;
|
|
9
16
|
disableItemCheckbox?: (item: T) => boolean;
|
|
@@ -37,8 +44,11 @@ export function useTableSelection<T extends TableItemType>(options: UseTableSele
|
|
|
37
44
|
return selection.value.length === items.value.length && (options.totalCount || 0) > items.value.length;
|
|
38
45
|
});
|
|
39
46
|
|
|
47
|
+
// Use Set for O(1) selection lookups instead of O(n) array search with deep equality
|
|
48
|
+
const selectionIds = computed(() => new Set(selection.value.map(getItemId)));
|
|
49
|
+
|
|
40
50
|
function isSelected(item: T): boolean {
|
|
41
|
-
return
|
|
51
|
+
return selectionIds.value.has(getItemId(item));
|
|
42
52
|
}
|
|
43
53
|
|
|
44
54
|
function handleSelectAll(): void {
|
|
@@ -52,14 +62,15 @@ export function useTableSelection<T extends TableItemType>(options: UseTableSele
|
|
|
52
62
|
}
|
|
53
63
|
|
|
54
64
|
function rowCheckbox(item: T): void {
|
|
55
|
-
|
|
65
|
+
const itemId = getItemId(item);
|
|
66
|
+
const disabledIds = new Set(disabledSelection.value.map(getItemId));
|
|
67
|
+
|
|
68
|
+
if (disabledIds.has(itemId)) {
|
|
56
69
|
return;
|
|
57
70
|
}
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (index !== -1) {
|
|
62
|
-
selection.value = selection.value.filter((_, i) => i !== index);
|
|
72
|
+
if (selectionIds.value.has(itemId)) {
|
|
73
|
+
selection.value = selection.value.filter((x) => getItemId(x) !== itemId);
|
|
63
74
|
} else {
|
|
64
75
|
selection.value = [...selection.value, item];
|
|
65
76
|
}
|
|
@@ -67,16 +78,11 @@ export function useTableSelection<T extends TableItemType>(options: UseTableSele
|
|
|
67
78
|
|
|
68
79
|
async function handleMultiselect(items: T[]): Promise<void> {
|
|
69
80
|
if (disableItemCheckbox && typeof disableItemCheckbox === "function") {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
disabledMultiselect.push(item);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
disabledSelection.value = disabledMultiselect;
|
|
81
|
+
// Use Promise.all for parallel execution instead of sequential awaits
|
|
82
|
+
const objectItems = items.filter((item) => typeof item === "object");
|
|
83
|
+
const results = await Promise.all(objectItems.map((item) => disableItemCheckbox(item)));
|
|
84
|
+
|
|
85
|
+
disabledSelection.value = objectItems.filter((_, index) => results[index]);
|
|
80
86
|
}
|
|
81
87
|
}
|
|
82
88
|
|
|
@@ -84,7 +90,9 @@ export function useTableSelection<T extends TableItemType>(options: UseTableSele
|
|
|
84
90
|
() => items.value,
|
|
85
91
|
(newItems) => {
|
|
86
92
|
handleMultiselect(newItems);
|
|
87
|
-
|
|
93
|
+
// Use Set for O(1) lookups when filtering selection
|
|
94
|
+
const newItemIds = new Set(newItems.map(getItemId));
|
|
95
|
+
selection.value = selection.value.filter((item) => newItemIds.has(getItemId(item)));
|
|
88
96
|
},
|
|
89
97
|
{ deep: true, immediate: true },
|
|
90
98
|
);
|
|
@@ -4,6 +4,9 @@ import { useLocalStorage } from "@vueuse/core";
|
|
|
4
4
|
import { cloneDeep, pick, unionBy } from "lodash-es";
|
|
5
5
|
import { TableColPartial } from "../types";
|
|
6
6
|
import { ITableColumns } from "../../../../../core/types";
|
|
7
|
+
import { createLogger } from "../../../../../core/utilities";
|
|
8
|
+
|
|
9
|
+
const logger = createLogger("vc-table-state");
|
|
7
10
|
|
|
8
11
|
export interface UseTableStateOptions {
|
|
9
12
|
stateKey: Ref<string, string>;
|
|
@@ -47,7 +50,7 @@ export function useTableState(options: UseTableStateOptions) {
|
|
|
47
50
|
});
|
|
48
51
|
|
|
49
52
|
function saveState() {
|
|
50
|
-
|
|
53
|
+
logger.debug("Save state");
|
|
51
54
|
const colsClone = cloneDeep(internalColumns.value);
|
|
52
55
|
state.value = colsClone.map((col) => pick(col, "id", "visible", "width", "predefined", "title"));
|
|
53
56
|
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Ref, ref } from "vue";
|
|
2
|
-
|
|
3
|
-
export interface GlobalSearchState {
|
|
4
|
-
isSearchVisible: Ref<Record<string, boolean>>;
|
|
5
|
-
searchQuery: Ref<Record<string, string>>;
|
|
6
|
-
toggleSearch: (bladeId: string) => void;
|
|
7
|
-
setSearchQuery: (bladeId: string, query: string) => void;
|
|
8
|
-
closeSearch: (bladeId: string) => void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function createGlobalSearchService() {
|
|
12
|
-
const isSearchVisible = ref<Record<string, boolean>>({});
|
|
13
|
-
const searchQuery = ref<Record<string, string>>({});
|
|
14
|
-
|
|
15
|
-
const toggleSearch = (bladeId: string) => {
|
|
16
|
-
isSearchVisible.value[bladeId] = !isSearchVisible.value[bladeId];
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const setSearchQuery = (bladeId: string, query: string) => {
|
|
20
|
-
searchQuery.value[bladeId] = query;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const closeSearch = (bladeId: string) => {
|
|
24
|
-
isSearchVisible.value[bladeId] = false;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const state: GlobalSearchState = {
|
|
28
|
-
isSearchVisible,
|
|
29
|
-
searchQuery,
|
|
30
|
-
toggleSearch,
|
|
31
|
-
setSearchQuery,
|
|
32
|
-
closeSearch,
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
return state;
|
|
36
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Ref } from "vue";
|
|
2
|
-
export interface GlobalSearchState {
|
|
3
|
-
isSearchVisible: Ref<Record<string, boolean>>;
|
|
4
|
-
searchQuery: Ref<Record<string, string>>;
|
|
5
|
-
toggleSearch: (bladeId: string) => void;
|
|
6
|
-
setSearchQuery: (bladeId: string, query: string) => void;
|
|
7
|
-
closeSearch: (bladeId: string) => void;
|
|
8
|
-
}
|
|
9
|
-
export declare function createGlobalSearchService(): GlobalSearchState;
|
|
10
|
-
//# sourceMappingURL=global-search-service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"global-search-service.d.ts","sourceRoot":"","sources":["../../../core/services/global-search-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAO,MAAM,KAAK,CAAC;AAE/B,MAAM,WAAW,iBAAiB;IAChC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC9C,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,yBAAyB,sBAyBxC"}
|