@amirjalili1374/ui-kit 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/README.md +275 -0
- package/dist/_redirects +1 -0
- package/dist/components/Loading.vue.d.ts +3 -0
- package/dist/components/Loading.vue.d.ts.map +1 -0
- package/dist/components/common/AppStepper.vue.d.ts +75 -0
- package/dist/components/common/AppStepper.vue.d.ts.map +1 -0
- package/dist/components/shared/BaseBreadcrumb.vue.d.ts +18 -0
- package/dist/components/shared/BaseBreadcrumb.vue.d.ts.map +1 -0
- package/dist/components/shared/BaseIcon.vue.d.ts +33 -0
- package/dist/components/shared/BaseIcon.vue.d.ts.map +1 -0
- package/dist/components/shared/ConfirmDialog.vue.d.ts +38 -0
- package/dist/components/shared/ConfirmDialog.vue.d.ts.map +1 -0
- package/dist/components/shared/CustomAutocomplete.vue.d.ts +81 -0
- package/dist/components/shared/CustomAutocomplete.vue.d.ts.map +1 -0
- package/dist/components/shared/CustomDataTable.vue.d.ts +59 -0
- package/dist/components/shared/CustomDataTable.vue.d.ts.map +1 -0
- package/dist/components/shared/DescriptionInput.vue.d.ts +34 -0
- package/dist/components/shared/DescriptionInput.vue.d.ts.map +1 -0
- package/dist/components/shared/DownloadButton.vue.d.ts +25 -0
- package/dist/components/shared/DownloadButton.vue.d.ts.map +1 -0
- package/dist/components/shared/MoneyInput.vue.d.ts +127 -0
- package/dist/components/shared/MoneyInput.vue.d.ts.map +1 -0
- package/dist/components/shared/PdfViewer.vue.d.ts +67 -0
- package/dist/components/shared/PdfViewer.vue.d.ts.map +1 -0
- package/dist/components/shared/ShamsiDatePicker.vue.d.ts +48 -0
- package/dist/components/shared/ShamsiDatePicker.vue.d.ts.map +1 -0
- package/dist/components/shared/UiChildCard.vue.d.ts +14 -0
- package/dist/components/shared/UiChildCard.vue.d.ts.map +1 -0
- package/dist/components/shared/UiParentCard.vue.d.ts +18 -0
- package/dist/components/shared/UiParentCard.vue.d.ts.map +1 -0
- package/dist/components/shared/VPriceTextField.vue.d.ts +30 -0
- package/dist/components/shared/VPriceTextField.vue.d.ts.map +1 -0
- package/dist/composables/useDataTable.d.ts +36 -0
- package/dist/composables/useDataTable.d.ts.map +1 -0
- package/dist/composables/useTableActions.d.ts +294 -0
- package/dist/composables/useTableActions.d.ts.map +1 -0
- package/dist/composables/useTableHeaders.d.ts +80 -0
- package/dist/composables/useTableHeaders.d.ts.map +1 -0
- package/dist/composables/useTableSelection.d.ts +32 -0
- package/dist/composables/useTableSelection.d.ts.map +1 -0
- package/dist/constants/enums/booleanEnum.d.ts +13 -0
- package/dist/constants/enums/booleanEnum.d.ts.map +1 -0
- package/dist/directives/v-digit-limit.d.ts +6 -0
- package/dist/directives/v-digit-limit.d.ts.map +1 -0
- package/dist/directives/v-permission.d.ts +3 -0
- package/dist/directives/v-permission.d.ts.map +1 -0
- package/dist/favicon.svg +13 -0
- package/dist/index.d.ts +53 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/persian.json +1 -0
- package/dist/plugins/mdi-icon.d.ts +16 -0
- package/dist/plugins/mdi-icon.d.ts.map +1 -0
- package/dist/services/apiService.d.ts +21 -0
- package/dist/services/apiService.d.ts.map +1 -0
- package/dist/services/axiosInstance.d.ts +11 -0
- package/dist/services/axiosInstance.d.ts.map +1 -0
- package/dist/stores/customizer.d.ts +47 -0
- package/dist/stores/customizer.d.ts.map +1 -0
- package/dist/stores/permissions.d.ts +47 -0
- package/dist/stores/permissions.d.ts.map +1 -0
- package/dist/style.css +5 -0
- package/dist/types/componentTypes/DataTableType.d.ts +14 -0
- package/dist/types/componentTypes/DataTableType.d.ts.map +1 -0
- package/dist/types/componentTypes/DataTableTypes.d.ts +120 -0
- package/dist/types/componentTypes/DataTableTypes.d.ts.map +1 -0
- package/dist/ui-kit.cjs.js +2 -0
- package/dist/ui-kit.cjs.js.map +1 -0
- package/dist/ui-kit.es.js +36840 -0
- package/dist/ui-kit.es.js.map +1 -0
- package/dist/utils/NationalCodeValidator.d.ts +4 -0
- package/dist/utils/NationalCodeValidator.d.ts.map +1 -0
- package/dist/utils/date-convertor.d.ts +5 -0
- package/dist/utils/date-convertor.d.ts.map +1 -0
- package/dist/utils/greetingUtils.d.ts +35 -0
- package/dist/utils/greetingUtils.d.ts.map +1 -0
- package/dist/utils/helpers/fetch-wrapper.d.ts +23 -0
- package/dist/utils/helpers/fetch-wrapper.d.ts.map +1 -0
- package/dist/utils/number-formatter.d.ts +16 -0
- package/dist/utils/number-formatter.d.ts.map +1 -0
- package/dist/validators/nationalCodeRule.d.ts +2 -0
- package/dist/validators/nationalCodeRule.d.ts.map +1 -0
- package/package.json +134 -0
- package/src/assets/fonts/A Massir Spray.ttf +0 -0
- package/src/assets/fonts/BYekan.ttf +0 -0
- package/src/assets/fonts/BYekan.woff +0 -0
- package/src/assets/fonts/BYekan.woff2 +0 -0
- package/src/assets/fonts/Dima Shekasteh 2 Free.ttf +0 -0
- package/src/assets/fonts/Dima Shekasteh Free Regular.ttf +0 -0
- package/src/assets/fonts/IRANSansWeb.ts +1 -0
- package/src/assets/fonts/IRANSansWeb.ttf +0 -0
- package/src/assets/fonts/IRANSansXBlack.ttf +0 -0
- package/src/assets/fonts/IRANSansXBold.ttf +0 -0
- package/src/assets/fonts/IRANSansXDemiBold.ttf +0 -0
- package/src/assets/fonts/IRANSansXExtraBold.ttf +0 -0
- package/src/assets/fonts/IRANSansXLight.ttf +0 -0
- package/src/assets/fonts/IRANSansXMedium.ttf +0 -0
- package/src/assets/fonts/IRANSansXRegular.ttf +0 -0
- package/src/assets/fonts/IRANSansXThin.ttf +0 -0
- package/src/assets/fonts/IRANSansXUltraLight.ttf +0 -0
- package/src/assets/fonts/IranNastaliq.ttf +0 -0
- package/src/assets/fonts/Vazir-Medium-FD.ttf +0 -0
- package/src/assets/fonts/Vazir-Medium-FD.woff +0 -0
- package/src/assets/fonts/Vazir-Medium-FD.woff2 +0 -0
- package/src/assets/fonts/Vazir-Regular-FD.eot +0 -0
- package/src/assets/fonts/kalamehBold.woff +0 -0
- package/src/assets/fonts/kalamehBold.woff2 +0 -0
- package/src/assets/fonts/kalamehHeavy.woff +0 -0
- package/src/assets/fonts/kalamehHeavy.woff2 +0 -0
- package/src/assets/fonts/kalamehLight.woff +0 -0
- package/src/assets/fonts/kalamehLight.woff2 +0 -0
- package/src/assets/fonts/kalamehRegular.woff +0 -0
- package/src/assets/fonts/kalamehRegular.woff2 +0 -0
- package/src/assets/images/auth/social-google.svg +6 -0
- package/src/assets/images/favicon.svg +18 -0
- package/src/assets/images/icons/icon-card.svg +5 -0
- package/src/assets/images/logos/logo.svg +12 -0
- package/src/assets/images/logos/logolight.svg +12 -0
- package/src/assets/images/maintenance/img-error-bg.svg +34 -0
- package/src/assets/images/maintenance/img-error-blue.svg +43 -0
- package/src/assets/images/maintenance/img-error-purple.svg +42 -0
- package/src/assets/images/maintenance/img-error-text.svg +27 -0
- package/src/assets/images/profile/profile-user-account-svgrepo-com.svg +12 -0
- package/src/assets/images/profile/user-round.svg +15 -0
- package/src/assets/images/template/template-01.ts +1 -0
- package/src/assets/images/vectors/colorized-bg.svg +40 -0
- package/src/assets/images/vectors/logo_stroke_1px.svg +26 -0
- package/src/assets/images/vectors/logo_stroke_2px.svg +26 -0
- package/src/assets/scss/components/_approval-sections.scss +75 -0
- package/src/assets/styles/fonts.scss +77 -0
- package/src/components/Loading.vue +88 -0
- package/src/components/common/AppStepper.vue +139 -0
- package/src/components/shared/BaseBreadcrumb.vue +55 -0
- package/src/components/shared/BaseIcon.vue +27 -0
- package/src/components/shared/ConfirmDialog.vue +72 -0
- package/src/components/shared/CustomAutocomplete.vue +306 -0
- package/src/components/shared/CustomDataTable.vue +1859 -0
- package/src/components/shared/DescriptionInput.vue +204 -0
- package/src/components/shared/DownloadButton.vue +169 -0
- package/src/components/shared/MoneyInput.vue +105 -0
- package/src/components/shared/PdfViewer.vue +645 -0
- package/src/components/shared/ShamsiDatePicker.vue +444 -0
- package/src/components/shared/UiChildCard.vue +17 -0
- package/src/components/shared/UiParentCard.vue +21 -0
- package/src/components/shared/VPriceTextField.vue +136 -0
- package/src/composables/useDataTable.ts +152 -0
- package/src/composables/usePermissions.ts +90 -0
- package/src/composables/useRouteGuard.ts +36 -0
- package/src/composables/useTableActions.ts +207 -0
- package/src/composables/useTableHeaders.ts +172 -0
- package/src/composables/useTableSelection.ts +201 -0
- package/src/constants/enums/approval.ts +13 -0
- package/src/constants/enums/booleanEnum.ts +11 -0
- package/src/constants/enums/contractType.ts +11 -0
- package/src/constants/enums/lcProductType.ts +21 -0
- package/src/constants/enums/repaymentType.ts +11 -0
- package/src/directives/v-digit-limit.ts +15 -0
- package/src/directives/v-permission.ts +31 -0
- package/src/features/index.ts +48 -0
- package/src/index.ts +119 -0
- package/src/plugins/key-clock.ts +39 -0
- package/src/plugins/mdi-icon.ts +31 -0
- package/src/plugins/vuetify.ts +74 -0
- package/src/scss/_override.scss +72 -0
- package/src/scss/_variables.scss +124 -0
- package/src/scss/components/_VButtons.scss +23 -0
- package/src/scss/components/_VCard.scss +20 -0
- package/src/scss/components/_VCustomDataTable.scss +282 -0
- package/src/scss/components/_VField.scss +9 -0
- package/src/scss/components/_VInput.scss +17 -0
- package/src/scss/components/_VNavigationDrawer.scss +3 -0
- package/src/scss/components/_VShadow.scss +3 -0
- package/src/scss/components/_VStepper.scss +235 -0
- package/src/scss/components/_VTabs.scss +11 -0
- package/src/scss/components/_VTextField.scss +40 -0
- package/src/scss/components/_approval.scss +128 -0
- package/src/scss/layout/_container.scss +147 -0
- package/src/scss/layout/_sidebar.scss +138 -0
- package/src/scss/layout/_topbar.scss +39 -0
- package/src/scss/pages/_dashboards.scss +97 -0
- package/src/scss/style.scss +21 -0
- package/src/services/apiService.ts +59 -0
- package/src/services/axiosInstance.ts +14 -0
- package/src/stores/customizer.ts +55 -0
- package/src/stores/permissions.ts +237 -0
- package/src/theme/darkThemes/DarkModernTheme.ts +54 -0
- package/src/theme/darkThemes/DarkOrangeTheme.ts +53 -0
- package/src/theme/darkThemes/DarkPurpleTheme.ts +54 -0
- package/src/theme/darkThemes/DarkRedTheme.ts +54 -0
- package/src/theme/darkThemes/DarkSilverTheme.ts +53 -0
- package/src/theme/darkThemes/DarkSteelTealGreen.ts +53 -0
- package/src/theme/darkThemes/DarkTealTheme.ts +52 -0
- package/src/theme/lightThemes/ModernTheme.ts +55 -0
- package/src/theme/lightThemes/OrangeTheme.ts +54 -0
- package/src/theme/lightThemes/PurpleTheme.ts +54 -0
- package/src/theme/lightThemes/RedTheme.ts +55 -0
- package/src/theme/lightThemes/SilverTheme.ts +55 -0
- package/src/theme/lightThemes/SteelTealGreen.ts +54 -0
- package/src/theme/lightThemes/TealTheme.ts +54 -0
- package/src/types/approval/approvalType.ts +473 -0
- package/src/types/cartable/cartableTypes.ts +169 -0
- package/src/types/componentTypes/DataTableType.ts +14 -0
- package/src/types/componentTypes/DataTableTypes.ts +130 -0
- package/src/types/enums/global.ts +267 -0
- package/src/types/jalaali-js.d.ts +6 -0
- package/src/types/models/Base.ts +4 -0
- package/src/types/models/env.d.ts +10 -0
- package/src/types/models/person.ts +13 -0
- package/src/types/models/userInfo.ts +29 -0
- package/src/types/preApproval/preApprovalTypes.ts +67 -0
- package/src/types/shims-tabler-icons.d.ts +58 -0
- package/src/types/themeTypes/ThemeType.ts +47 -0
- package/src/types/vue-apexcharts.d.ts +1 -0
- package/src/types/vue3-print-nb.d.ts +1 -0
- package/src/types/vue_tabler_icon.d.ts +10 -0
- package/src/utils/NationalCodeValidator.ts +33 -0
- package/src/utils/date-convertor.ts +40 -0
- package/src/utils/greetingUtils.ts +97 -0
- package/src/utils/helpers/fake-backend.ts +68 -0
- package/src/utils/helpers/fetch-wrapper.ts +86 -0
- package/src/utils/number-formatter.ts +33 -0
- package/src/validators/nationalCodeRule.ts +6 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { ref, computed, watch } from 'vue';
|
|
2
|
+
import type { Ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
export interface SelectionOptions<T extends Record<string, any> = Record<string, any>> {
|
|
5
|
+
multiSelect?: boolean;
|
|
6
|
+
uniqueKey?: string | ((item: T) => string | number);
|
|
7
|
+
defaultSelected?: string;
|
|
8
|
+
groupBy?: string | ((item: T) => string | number);
|
|
9
|
+
defaultExpanded?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface GroupedItems<T extends Record<string, any> = Record<string, any>> {
|
|
13
|
+
groupKey: string | number;
|
|
14
|
+
groupLabel: string;
|
|
15
|
+
items: T[];
|
|
16
|
+
isExpanded: boolean;
|
|
17
|
+
count: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function useTableSelection<T extends Record<string, any> = Record<string, any>>(items: Ref<T[]>, options: SelectionOptions<T> = {}) {
|
|
21
|
+
const selectedItems = ref([]) as Ref<T[]>;
|
|
22
|
+
const expandedGroups = ref<Set<string | number>>(new Set());
|
|
23
|
+
const groupedItems = ref([] as GroupedItems<T>[]) as Ref<GroupedItems<T>[]>;
|
|
24
|
+
|
|
25
|
+
// Get unique value from item
|
|
26
|
+
const getUniqueValue = (item: T): string | number => {
|
|
27
|
+
if (typeof options.uniqueKey === 'function') {
|
|
28
|
+
return options.uniqueKey(item);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (typeof options.uniqueKey === 'string') {
|
|
32
|
+
return getNestedValue(item, options.uniqueKey);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// @ts-ignore - Fallback to id
|
|
36
|
+
return item.id;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Get nested value from object path
|
|
40
|
+
const getNestedValue = (obj: any, path: string): any => {
|
|
41
|
+
return path.split('.').reduce((o, p) => (o || {})[p], obj);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// Get group value from item
|
|
45
|
+
const getGroupValue = (item: T): string | number => {
|
|
46
|
+
if (!options.groupBy) return '';
|
|
47
|
+
|
|
48
|
+
if (typeof options.groupBy === 'function') {
|
|
49
|
+
return options.groupBy(item);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return getNestedValue(item, options.groupBy) || '';
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Toggle selection for a single item
|
|
56
|
+
const toggleSelection = (item: T) => {
|
|
57
|
+
const itemUniqueValue = getUniqueValue(item);
|
|
58
|
+
const index = (selectedItems.value as unknown as T[]).findIndex((selected: T) =>
|
|
59
|
+
getUniqueValue(selected) === itemUniqueValue
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (index > -1) {
|
|
63
|
+
(selectedItems.value as unknown as T[]).splice(index, 1);
|
|
64
|
+
} else if (options.multiSelect) {
|
|
65
|
+
(selectedItems.value as unknown as T[]).push(item);
|
|
66
|
+
} else {
|
|
67
|
+
selectedItems.value = [item] as unknown as T[];
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// Toggle select all items
|
|
72
|
+
const toggleSelectAll = () => {
|
|
73
|
+
if ((selectedItems.value as unknown as T[]).length === items.value.length) {
|
|
74
|
+
selectedItems.value = [] as unknown as T[];
|
|
75
|
+
} else {
|
|
76
|
+
selectedItems.value = [...(items.value as unknown as T[])];
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// Check if an item is selected
|
|
81
|
+
const isSelected = (item: T): boolean => {
|
|
82
|
+
const itemUniqueValue = getUniqueValue(item);
|
|
83
|
+
return (selectedItems.value as unknown as T[]).some((selected: T) =>
|
|
84
|
+
getUniqueValue(selected) === itemUniqueValue
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Clear all selections
|
|
89
|
+
const clearSelection = () => {
|
|
90
|
+
selectedItems.value = [];
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// Toggle group expansion
|
|
94
|
+
const toggleGroup = (groupKey: string | number) => {
|
|
95
|
+
// Prevent multiple rapid toggles and ensure state consistency
|
|
96
|
+
const isCurrentlyExpanded = expandedGroups.value.has(groupKey);
|
|
97
|
+
|
|
98
|
+
if (isCurrentlyExpanded) {
|
|
99
|
+
expandedGroups.value.delete(groupKey);
|
|
100
|
+
} else {
|
|
101
|
+
expandedGroups.value.add(groupKey);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Update the isExpanded property in groupedItems
|
|
105
|
+
const groupIndex = groupedItems.value.findIndex(group => group.groupKey === groupKey);
|
|
106
|
+
if (groupIndex !== -1) {
|
|
107
|
+
groupedItems.value[groupIndex].isExpanded = !isCurrentlyExpanded;
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
// Expand all groups
|
|
112
|
+
const expandAllGroups = () => {
|
|
113
|
+
groupedItems.value.forEach(group => {
|
|
114
|
+
expandedGroups.value.add(group.groupKey);
|
|
115
|
+
group.isExpanded = true;
|
|
116
|
+
});
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Collapse all groups
|
|
120
|
+
const collapseAllGroups = () => {
|
|
121
|
+
expandedGroups.value.clear();
|
|
122
|
+
groupedItems.value.forEach(group => {
|
|
123
|
+
group.isExpanded = false;
|
|
124
|
+
});
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// Group items by the specified property
|
|
128
|
+
const groupItems = (list: T[]) => {
|
|
129
|
+
if (!options.groupBy) {
|
|
130
|
+
groupedItems.value = [];
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const groups = new Map<string | number, T[]>();
|
|
135
|
+
|
|
136
|
+
// Group items by the specified property
|
|
137
|
+
list.forEach((item) => {
|
|
138
|
+
const groupKey = getGroupValue(item);
|
|
139
|
+
if (!groups.has(groupKey)) {
|
|
140
|
+
groups.set(groupKey, []);
|
|
141
|
+
}
|
|
142
|
+
groups.get(groupKey)!.push(item);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
// Convert to array format
|
|
146
|
+
groupedItems.value = Array.from(groups.entries()).map(([groupKey, groupItems]) => ({
|
|
147
|
+
groupKey,
|
|
148
|
+
groupLabel: getGroupLabel(groupKey, groupItems),
|
|
149
|
+
items: groupItems,
|
|
150
|
+
isExpanded: expandedGroups.value.has(groupKey) || options.defaultExpanded,
|
|
151
|
+
count: groupItems.length
|
|
152
|
+
})) as unknown as GroupedItems<T>[];
|
|
153
|
+
|
|
154
|
+
// Sort groups by key
|
|
155
|
+
groupedItems.value.sort((a, b) => {
|
|
156
|
+
if (typeof a.groupKey === 'string' && typeof b.groupKey === 'string') {
|
|
157
|
+
return a.groupKey.localeCompare(b.groupKey);
|
|
158
|
+
}
|
|
159
|
+
return a.groupKey < b.groupKey ? -1 : a.groupKey > b.groupKey ? 1 : 0;
|
|
160
|
+
});
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Get group label
|
|
164
|
+
const getGroupLabel = (groupKey: string | number, groupItems: T[]): string => {
|
|
165
|
+
return `${String(groupKey)} (${groupItems.length} رکورد)`;
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
// Watch for changes in items and group them if needed
|
|
169
|
+
watch(() => items.value, (newItems) => {
|
|
170
|
+
if (options.groupBy) {
|
|
171
|
+
groupItems(newItems as T[]);
|
|
172
|
+
}
|
|
173
|
+
}, { immediate: true, deep: true });
|
|
174
|
+
|
|
175
|
+
// Check if all items are selected
|
|
176
|
+
const allSelected = computed(() => {
|
|
177
|
+
return items.value.length > 0 && selectedItems.value.length === items.value.length;
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Check if some items are selected
|
|
181
|
+
const someSelected = computed(() => {
|
|
182
|
+
return selectedItems.value.length > 0 && !allSelected.value;
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
selectedItems,
|
|
187
|
+
groupedItems,
|
|
188
|
+
expandedGroups,
|
|
189
|
+
allSelected,
|
|
190
|
+
someSelected,
|
|
191
|
+
toggleSelection,
|
|
192
|
+
toggleSelectAll,
|
|
193
|
+
isSelected,
|
|
194
|
+
clearSelection,
|
|
195
|
+
toggleGroup,
|
|
196
|
+
expandAllGroups,
|
|
197
|
+
collapseAllGroups,
|
|
198
|
+
getGroupValue,
|
|
199
|
+
getUniqueValue
|
|
200
|
+
};
|
|
201
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const ApprovalTypeEnum = {
|
|
2
|
+
CASE: 'CASE',
|
|
3
|
+
MULTI_USE: 'MULTI_USE',
|
|
4
|
+
ANNUAL_LIMIT: 'ANNUAL_LIMIT',
|
|
5
|
+
} as const;
|
|
6
|
+
|
|
7
|
+
export type ApprovalType = (typeof ApprovalTypeEnum)[keyof typeof ApprovalTypeEnum];
|
|
8
|
+
|
|
9
|
+
export const ApprovalTypeOptions = [
|
|
10
|
+
{ title: 'موردی', value: ApprovalTypeEnum.CASE },
|
|
11
|
+
{ title: 'استفاده چند باره تا سقف', value: ApprovalTypeEnum.MULTI_USE },
|
|
12
|
+
{ title: 'حد سالانه', value: ApprovalTypeEnum.ANNUAL_LIMIT },
|
|
13
|
+
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const BooleanEnum = {
|
|
2
|
+
TRUE: true,
|
|
3
|
+
FALSE: false
|
|
4
|
+
} as const;
|
|
5
|
+
|
|
6
|
+
export type BooleanStatus = (typeof BooleanEnum)[keyof typeof BooleanEnum];
|
|
7
|
+
|
|
8
|
+
export const BooleanEnumOptions = [
|
|
9
|
+
{ title: '✅', value: BooleanEnum.TRUE },
|
|
10
|
+
{ title: '❌', value: BooleanEnum.FALSE }
|
|
11
|
+
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const ContractTypeEnum = {
|
|
2
|
+
IMPORT: 123,
|
|
3
|
+
EXPORT: 124,
|
|
4
|
+
} as const;
|
|
5
|
+
|
|
6
|
+
export type ContractType = (typeof ContractTypeEnum)[keyof typeof ContractTypeEnum];
|
|
7
|
+
|
|
8
|
+
export const ContractTypeOption = [
|
|
9
|
+
{ longTitle: 'اعتبار اسنادی وارداتی', value: ContractTypeEnum.IMPORT},
|
|
10
|
+
{ longTitle: 'اعتبار اسنادی صادراتی', value: ContractTypeEnum.EXPORT },
|
|
11
|
+
];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const LcProductTypeEnum = {
|
|
2
|
+
TRANSFER_CREDIT: 'TRANSFER_CREDIT',
|
|
3
|
+
INSIDE_LC: 'INSIDE_LC',
|
|
4
|
+
BACK_TO_BACK_LC: 'BACK_TO_BACK_LC',
|
|
5
|
+
NORMAL_LC: 'NORMAL_LC',
|
|
6
|
+
CUSTOMER_LC: 'CUSTOMER_LC',
|
|
7
|
+
NORMAL_EXPORT: 'NORMAL_EXPORT',
|
|
8
|
+
INTERNAL_INSIDE: 'INTERNAL_INSIDE'
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
11
|
+
export type LcProductType = (typeof LcProductTypeEnum)[keyof typeof LcProductTypeEnum];
|
|
12
|
+
|
|
13
|
+
export const LcProductOption = [
|
|
14
|
+
{ title: 'Transfer Of a Documentary Credit', value: LcProductTypeEnum.TRANSFER_CREDIT },
|
|
15
|
+
{ title: 'اعتبار اسنادی داخلی', value: LcProductTypeEnum.INSIDE_LC },
|
|
16
|
+
{ title: 'Back to Back L/C', value: LcProductTypeEnum.BACK_TO_BACK_LC },
|
|
17
|
+
{ title: 'اعتبار اسنادی وارداتی عادی', value: LcProductTypeEnum.NORMAL_LC },
|
|
18
|
+
{ title: 'مشتریان بانکی', value: LcProductTypeEnum.CUSTOMER_LC },
|
|
19
|
+
{ title: 'اعتبار اسنادی صادراتی عادی', value: LcProductTypeEnum.NORMAL_EXPORT },
|
|
20
|
+
{ title: 'اعتبار اسنادی صادراتی داخلی', value: LcProductTypeEnum.INTERNAL_INSIDE },
|
|
21
|
+
];
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export const RepaymentTypeEnum = {
|
|
2
|
+
INSTALLMENT: 'INSTALLMENT',
|
|
3
|
+
NON_INSTALLMENT: 'NON_INSTALLMENT',
|
|
4
|
+
} as const;
|
|
5
|
+
|
|
6
|
+
export type RepaymentType = (typeof RepaymentTypeEnum)[keyof typeof RepaymentTypeEnum];
|
|
7
|
+
|
|
8
|
+
export const RepaymentTypeOptions = [
|
|
9
|
+
{ title: 'تدریجی', value: RepaymentTypeEnum.INSTALLMENT },
|
|
10
|
+
{ title: 'یکجا', value: RepaymentTypeEnum.NON_INSTALLMENT },
|
|
11
|
+
];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DirectiveBinding } from 'vue'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
mounted(el: HTMLInputElement, binding: DirectiveBinding<number>) {
|
|
5
|
+
const maxDigits = binding.value
|
|
6
|
+
|
|
7
|
+
const handleInput = (e: Event) => {
|
|
8
|
+
const input = e.target as HTMLInputElement
|
|
9
|
+
input.value = input.value.replace(/\D/g, '').slice(0, maxDigits)
|
|
10
|
+
input.dispatchEvent(new Event('input')) // Sync v-model
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
el.addEventListener('input', handleInput)
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Directive } from 'vue';
|
|
2
|
+
import { usePermissionsStore } from '@/stores/permissions';
|
|
3
|
+
|
|
4
|
+
export const vPermission: Directive = {
|
|
5
|
+
mounted(el, binding) {
|
|
6
|
+
const permissionsStore = usePermissionsStore();
|
|
7
|
+
|
|
8
|
+
// Check if user has permission for the specified menu key
|
|
9
|
+
const hasPermission = permissionsStore.hasMenuPermission(binding.value);
|
|
10
|
+
|
|
11
|
+
if (!hasPermission) {
|
|
12
|
+
// Hide the element if user doesn't have permission
|
|
13
|
+
el.style.display = 'none';
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
updated(el, binding) {
|
|
18
|
+
const permissionsStore = usePermissionsStore();
|
|
19
|
+
|
|
20
|
+
// Check if user has permission for the specified menu key
|
|
21
|
+
const hasPermission = permissionsStore.hasMenuPermission(binding.value);
|
|
22
|
+
|
|
23
|
+
if (!hasPermission) {
|
|
24
|
+
// Hide the element if user doesn't have permission
|
|
25
|
+
el.style.display = 'none';
|
|
26
|
+
} else {
|
|
27
|
+
// Show the element if user has permission
|
|
28
|
+
el.style.display = '';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feature-based module exports
|
|
3
|
+
* This file provides barrel exports for all features
|
|
4
|
+
*
|
|
5
|
+
* Note: This is a placeholder for future feature-based organization.
|
|
6
|
+
* Currently, the project uses a traditional structure which is working well.
|
|
7
|
+
*
|
|
8
|
+
* Future structure could be:
|
|
9
|
+
* src/features/
|
|
10
|
+
* ├── approval/
|
|
11
|
+
* │ ├── components/
|
|
12
|
+
* │ ├── composables/
|
|
13
|
+
* │ ├── services/
|
|
14
|
+
* │ └── types/
|
|
15
|
+
* ├── cartable/
|
|
16
|
+
* │ ├── components/
|
|
17
|
+
* │ ├── composables/
|
|
18
|
+
* │ ├── services/
|
|
19
|
+
* │ └── types/
|
|
20
|
+
* └── dashboard/
|
|
21
|
+
* ├── components/
|
|
22
|
+
* ├── composables/
|
|
23
|
+
* ├── services/
|
|
24
|
+
* └── types/
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
// Re-export from current structure for compatibility
|
|
28
|
+
// Note: Individual component exports would need index files in each directory
|
|
29
|
+
|
|
30
|
+
// Re-export services
|
|
31
|
+
export * from '../services/modules/approval';
|
|
32
|
+
export * from '../services/modules/cartable';
|
|
33
|
+
export * from '../services/modules/user';
|
|
34
|
+
|
|
35
|
+
// Re-export types
|
|
36
|
+
export * from '../types/approval/approvalType';
|
|
37
|
+
export * from '../types/cartable/cartableTypes';
|
|
38
|
+
export * from '../types/models/person';
|
|
39
|
+
export * from '../types/models/userInfo';
|
|
40
|
+
|
|
41
|
+
// Re-export composables
|
|
42
|
+
export * from '../composables/useDataTable';
|
|
43
|
+
export * from '../composables/usePermissions';
|
|
44
|
+
export * from '../composables/useRouteGuard';
|
|
45
|
+
export * from '../composables/useTableActions';
|
|
46
|
+
export * from '../composables/useTableHeaders';
|
|
47
|
+
export * from '../composables/useTableSelection';
|
|
48
|
+
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UI Kit Library Entry Point
|
|
3
|
+
*
|
|
4
|
+
* This file exports only generic, reusable components, composables, utilities, directives,
|
|
5
|
+
* stores, and component types - NO business logic or app-specific types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Import styles (this ensures CSS is bundled)
|
|
9
|
+
import './scss/style.scss';
|
|
10
|
+
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// COMPONENTS - Global reusable UI components only
|
|
13
|
+
// ============================================================================
|
|
14
|
+
|
|
15
|
+
// Components - Shared
|
|
16
|
+
export { default as BaseBreadcrumb } from './components/shared/BaseBreadcrumb.vue';
|
|
17
|
+
export { default as BaseIcon } from './components/shared/BaseIcon.vue';
|
|
18
|
+
export { default as ConfirmDialog } from './components/shared/ConfirmDialog.vue';
|
|
19
|
+
export { default as CustomAutocomplete } from './components/shared/CustomAutocomplete.vue';
|
|
20
|
+
export { default as CustomDataTable } from './components/shared/CustomDataTable.vue';
|
|
21
|
+
export { default as DescriptionInput } from './components/shared/DescriptionInput.vue';
|
|
22
|
+
export { default as DownloadButton } from './components/shared/DownloadButton.vue';
|
|
23
|
+
export { default as MoneyInput } from './components/shared/MoneyInput.vue';
|
|
24
|
+
export { default as PdfViewer } from './components/shared/PdfViewer.vue';
|
|
25
|
+
export { default as ShamsiDatePicker } from './components/shared/ShamsiDatePicker.vue';
|
|
26
|
+
export { default as UiChildCard } from './components/shared/UiChildCard.vue';
|
|
27
|
+
export { default as UiParentCard } from './components/shared/UiParentCard.vue';
|
|
28
|
+
export { default as VPriceTextField } from './components/shared/VPriceTextField.vue';
|
|
29
|
+
|
|
30
|
+
// Components - Common
|
|
31
|
+
export { default as AppStepper } from './components/common/AppStepper.vue';
|
|
32
|
+
export { default as Loading } from './components/Loading.vue';
|
|
33
|
+
|
|
34
|
+
// ============================================================================
|
|
35
|
+
// COMPOSABLES - Generic composables only (no business logic)
|
|
36
|
+
// ============================================================================
|
|
37
|
+
|
|
38
|
+
// Export functions only to avoid type conflicts with component types
|
|
39
|
+
export { useDataTable } from './composables/useDataTable';
|
|
40
|
+
export type { DataTableOptions, PaginationState } from './composables/useDataTable';
|
|
41
|
+
|
|
42
|
+
export { useTableActions } from './composables/useTableActions';
|
|
43
|
+
export type { ActionOptions } from './composables/useTableActions';
|
|
44
|
+
// Note: CustomAction and CustomButtonAction types are exported from DataTableTypes
|
|
45
|
+
|
|
46
|
+
export * from './composables/useTableHeaders';
|
|
47
|
+
|
|
48
|
+
export { useTableSelection } from './composables/useTableSelection';
|
|
49
|
+
export type { SelectionOptions } from './composables/useTableSelection';
|
|
50
|
+
// Note: GroupedItems type is exported from DataTableTypes
|
|
51
|
+
|
|
52
|
+
// Note: usePermissions and useRouteGuard are app-specific and excluded
|
|
53
|
+
|
|
54
|
+
// ============================================================================
|
|
55
|
+
// DIRECTIVES - All directives
|
|
56
|
+
// ============================================================================
|
|
57
|
+
|
|
58
|
+
export { default as DigitLimit } from './directives/v-digit-limit';
|
|
59
|
+
// Note: v-permission directive contains app-specific logic and is excluded
|
|
60
|
+
|
|
61
|
+
// ============================================================================
|
|
62
|
+
// UTILS - Generic utility functions only
|
|
63
|
+
// ============================================================================
|
|
64
|
+
|
|
65
|
+
export * from './utils/date-convertor';
|
|
66
|
+
export * from './utils/greetingUtils';
|
|
67
|
+
export * from './utils/number-formatter';
|
|
68
|
+
export * from './utils/NationalCodeValidator';
|
|
69
|
+
export * from './utils/helpers/fetch-wrapper';
|
|
70
|
+
export { configureAuth } from './utils/helpers/fetch-wrapper';
|
|
71
|
+
export type { AuthConfig } from './utils/helpers/fetch-wrapper';
|
|
72
|
+
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// VALIDATORS - Generic validators
|
|
75
|
+
// ============================================================================
|
|
76
|
+
|
|
77
|
+
export * from './validators/nationalCodeRule';
|
|
78
|
+
|
|
79
|
+
// ============================================================================
|
|
80
|
+
// STORES - Global stores only (no business logic stores)
|
|
81
|
+
// ============================================================================
|
|
82
|
+
|
|
83
|
+
export { useCustomizerStore } from './stores/customizer';
|
|
84
|
+
|
|
85
|
+
// Note: permissions store contains app-specific menu permissions and is excluded
|
|
86
|
+
// Note: approval, base, customerInfo, auth, authUser stores are app-specific and excluded
|
|
87
|
+
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// TYPES - Component types and generic types only (NO business logic types)
|
|
90
|
+
// ============================================================================
|
|
91
|
+
|
|
92
|
+
// Component types - These are the definitive types for components
|
|
93
|
+
export * from './types/componentTypes/DataTableType';
|
|
94
|
+
export * from './types/componentTypes/DataTableTypes';
|
|
95
|
+
|
|
96
|
+
// Generic enum types
|
|
97
|
+
export * from './constants/enums/booleanEnum';
|
|
98
|
+
|
|
99
|
+
// Note: All approval, cartable, and other business logic types are excluded
|
|
100
|
+
|
|
101
|
+
// Plugin installation function (for Vue app.use())
|
|
102
|
+
import type { App } from 'vue';
|
|
103
|
+
import DigitLimit from './directives/v-digit-limit';
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Install the UI Kit library in a Vue application
|
|
107
|
+
* @param app - Vue application instance
|
|
108
|
+
*/
|
|
109
|
+
export function install(app: App) {
|
|
110
|
+
// Register directives globally
|
|
111
|
+
app.directive('digit-limit', DigitLimit);
|
|
112
|
+
// Note: v-permission directive contains app-specific logic and is not registered
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Default export for plugin usage
|
|
116
|
+
export default {
|
|
117
|
+
install,
|
|
118
|
+
};
|
|
119
|
+
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keycloak Plugin Configuration
|
|
3
|
+
*
|
|
4
|
+
* Keycloak authentication plugin for Vue 3 application
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { App } from 'vue'
|
|
8
|
+
import VueKeycloakJs from '@dsb-norge/vue-keycloak-js'
|
|
9
|
+
|
|
10
|
+
export function setupKeycloak(app: App) {
|
|
11
|
+
return app.use(VueKeycloakJs, {
|
|
12
|
+
config: {
|
|
13
|
+
realm: 'master',
|
|
14
|
+
url: 'http://192.168.251.72:8080',
|
|
15
|
+
clientId: 'FACILITY',
|
|
16
|
+
},
|
|
17
|
+
init: {
|
|
18
|
+
flow: 'standard',
|
|
19
|
+
checkLoginIframe: false,
|
|
20
|
+
onLoad: 'login-required',
|
|
21
|
+
pkceMethod: 'S256',
|
|
22
|
+
},
|
|
23
|
+
logout: {
|
|
24
|
+
redirectUri: window.location.origin
|
|
25
|
+
},
|
|
26
|
+
onAuthLogout: () => {
|
|
27
|
+
console.log('User logged out from Keycloak')
|
|
28
|
+
// You can add additional cleanup here if needed
|
|
29
|
+
},
|
|
30
|
+
onReady: (keycloakInstance) => {
|
|
31
|
+
// Expose Keycloak instance globally for axios interceptor
|
|
32
|
+
(window as any).$keycloak = keycloakInstance;
|
|
33
|
+
console.log('Keycloak ready, instance exposed globally');
|
|
34
|
+
},
|
|
35
|
+
onInitError: (error) => {
|
|
36
|
+
console.error('Keycloak initialization error:', error);
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {
|
|
2
|
+
mdiClose,
|
|
3
|
+
mdiHome,
|
|
4
|
+
mdiEyeOff,
|
|
5
|
+
mdiEye,
|
|
6
|
+
mdiFormatSize,
|
|
7
|
+
mdiPaletteSwatchVariant,
|
|
8
|
+
mdiFileDownload,
|
|
9
|
+
mdiCheckCircle,
|
|
10
|
+
mdiAlertCircle,
|
|
11
|
+
mdiPencil,
|
|
12
|
+
mdiDelete,
|
|
13
|
+
mdiArrowRight,
|
|
14
|
+
mdiCog
|
|
15
|
+
} from '@mdi/js';
|
|
16
|
+
|
|
17
|
+
export const icons = {
|
|
18
|
+
close: mdiClose,
|
|
19
|
+
home: mdiHome,
|
|
20
|
+
eyeOff: mdiEyeOff,
|
|
21
|
+
eye: mdiEye,
|
|
22
|
+
text: mdiFormatSize,
|
|
23
|
+
style: mdiPaletteSwatchVariant,
|
|
24
|
+
download: mdiFileDownload,
|
|
25
|
+
checkCircle: mdiCheckCircle,
|
|
26
|
+
alertCircle: mdiAlertCircle,
|
|
27
|
+
pencil: mdiPencil,
|
|
28
|
+
delete: mdiDelete,
|
|
29
|
+
arrowRight: mdiArrowRight,
|
|
30
|
+
cog: mdiCog
|
|
31
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createVuetify } from 'vuetify';
|
|
2
|
+
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg';
|
|
3
|
+
import { icons } from './mdi-icon'; // Import icons from separate file
|
|
4
|
+
import * as components from 'vuetify/components';
|
|
5
|
+
import * as directives from 'vuetify/directives';
|
|
6
|
+
|
|
7
|
+
// Light Themes
|
|
8
|
+
import { ModernTheme } from '@/theme/lightThemes/ModernTheme';
|
|
9
|
+
import { PurpleTheme } from '@/theme/lightThemes/PurpleTheme';
|
|
10
|
+
import { RedTheme } from '@/theme/lightThemes/RedTheme';
|
|
11
|
+
import { OrangeTheme } from '@/theme/lightThemes/OrangeTheme';
|
|
12
|
+
import { SteelTealGreen } from '@/theme/lightThemes/SteelTealGreen';
|
|
13
|
+
import { TealTheme } from '@/theme/lightThemes/TealTheme';
|
|
14
|
+
import { SilverTheme } from '@/theme/lightThemes/SilverTheme';
|
|
15
|
+
|
|
16
|
+
// Dark Themes
|
|
17
|
+
import { DarkModernTheme } from '@/theme/darkThemes/DarkModernTheme';
|
|
18
|
+
import { DarkOrangeTheme } from '@/theme/darkThemes/DarkOrangeTheme';
|
|
19
|
+
import { DarkPurpleTheme } from '@/theme/darkThemes/DarkPurpleTheme';
|
|
20
|
+
import { DarkSteelTealGreen } from '@/theme/darkThemes/DarkSteelTealGreen';
|
|
21
|
+
import { DarkTealTheme } from '@/theme/darkThemes/DarkTealTheme';
|
|
22
|
+
import { DarkSilverTheme } from '@/theme/darkThemes/DarkSilverTheme';
|
|
23
|
+
import { DarkRedTheme } from '@/theme/darkThemes/DarkRedTheme';
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export default createVuetify({
|
|
28
|
+
components,
|
|
29
|
+
directives,
|
|
30
|
+
icons: {
|
|
31
|
+
defaultSet: 'mdi',
|
|
32
|
+
aliases: {
|
|
33
|
+
...aliases,
|
|
34
|
+
...icons
|
|
35
|
+
},
|
|
36
|
+
sets: {
|
|
37
|
+
mdi
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
theme: {
|
|
41
|
+
defaultTheme: 'ModernTheme',
|
|
42
|
+
themes: {
|
|
43
|
+
// Light Themes
|
|
44
|
+
ModernTheme,
|
|
45
|
+
PurpleTheme,
|
|
46
|
+
RedTheme,
|
|
47
|
+
OrangeTheme,
|
|
48
|
+
SteelTealGreen,
|
|
49
|
+
TealTheme,
|
|
50
|
+
SilverTheme,
|
|
51
|
+
// Dark Themes
|
|
52
|
+
DarkModernTheme,
|
|
53
|
+
DarkOrangeTheme,
|
|
54
|
+
DarkPurpleTheme,
|
|
55
|
+
DarkSteelTealGreen,
|
|
56
|
+
DarkTealTheme,
|
|
57
|
+
DarkSilverTheme,
|
|
58
|
+
DarkRedTheme
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
defaults: {
|
|
62
|
+
VBtn: {},
|
|
63
|
+
VCard: {
|
|
64
|
+
rounded: 'md'
|
|
65
|
+
},
|
|
66
|
+
VTextField: {
|
|
67
|
+
rounded: 'lg'
|
|
68
|
+
},
|
|
69
|
+
VTooltip: {
|
|
70
|
+
// set v-tooltip default location to top
|
|
71
|
+
location: 'top'
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|