diff --git a/package-lock.json b/package-lock.json index 701f140c3..45d1b295d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@webitel/ui-sdk", - "version": "24.10.48", + "version": "24.10.49", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@webitel/ui-sdk", - "version": "24.10.48", + "version": "24.10.46-6", "dependencies": { "@floating-ui/vue": "^1.0.1", "@morev/vue-transitions": "^3.0.2", diff --git a/package.json b/package.json index d0230c414..04c74d5b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@webitel/ui-sdk", - "version": "24.10.48", + "version": "24.10.49", "private": false, "scripts": { "dev": "vite", diff --git a/src/composables/useAccessControl/useAccessControl.js b/src/composables/useAccessControl/useAccessControl.js new file mode 100644 index 000000000..3c1988123 --- /dev/null +++ b/src/composables/useAccessControl/useAccessControl.js @@ -0,0 +1,33 @@ +import { computed } from 'vue'; +import { useRoute } from 'vue-router'; +import { useStore } from 'vuex'; + +export const useAccessControl = () => { + const store = useStore(); + const route = useRoute(); + + const hasReadAccess = computed(() => store.getters['userinfo/HAS_READ_ACCESS']({ route })); + const hasCreateAccess = computed(() => store.getters['userinfo/HAS_CREATE_ACCESS']({ route })); + const hasEditAccess = computed(() => store.getters['userinfo/HAS_EDIT_ACCESS']({ route })); + const hasDeleteAccess = computed(() => store.getters['userinfo/HAS_DELETE_ACCESS']({ route })); + + const hasSaveActionAccess = computed(() => { + if (route.params.id === 'new') return hasEditAccess.value; + return hasCreateAccess.value; + }); + + const disableUserInput = computed(() => { + if (route.params.id === 'new') return !hasEditAccess.value; + return !hasCreateAccess.value; + }); + + return { + hasReadAccess, + hasCreateAccess, + hasEditAccess, + hasDeleteAccess, + + hasSaveActionAccess, + disableUserInput, + }; +}; diff --git a/src/composables/useCachedItemInstanceName/useCachedItemInstanceName.js b/src/composables/useCachedItemInstanceName/useCachedItemInstanceName.js new file mode 100644 index 000000000..26f8618fb --- /dev/null +++ b/src/composables/useCachedItemInstanceName/useCachedItemInstanceName.js @@ -0,0 +1,33 @@ +import get from 'lodash/get.js'; +import { onMounted, ref, watch } from 'vue'; + +export const useCachedItemInstanceName = (itemInstance, { namePath = 'name' } = {}) => { + const name = ref(''); + + const updateName = () => { + name.value = get(itemInstance.value, namePath); + }; + + watch( + () => itemInstance.value._dirty, + (value) => { + if (!value) updateName(); + }, + ); + + onMounted(() => { + // itemInstance._dirty isn't init as "false", + // so that we should set up first name representation in other way + const unwatch = watch( + () => itemInstance.value.name, + (name) => { + updateName(); + if (name) unwatch(); + }, + ); + }); + + return { + name, + }; +}; diff --git a/src/composables/useCard/useCardComponent.js b/src/composables/useCard/useCardComponent.js new file mode 100644 index 000000000..2ce6bbbe5 --- /dev/null +++ b/src/composables/useCard/useCardComponent.js @@ -0,0 +1,88 @@ +import { computed, onMounted, onUnmounted } from 'vue'; +import { useI18n } from 'vue-i18n'; +import { useRoute, useRouter } from 'vue-router'; + +import { useCachedItemInstanceName } from '../useCachedItemInstanceName/useCachedItemInstanceName.js'; + +export const useCardComponent = (params) => { + const { id, + itemInstance, + invalid, + + loadItem, + addItem, + updateItem, + setId, + resetState } = params; + + const router = useRouter(); + const route = useRoute(); + const { t } = useI18n(); + + const { name: pathName } = useCachedItemInstanceName(itemInstance); + + const isNew = computed(() => route.params.id === 'new'); + const disabledSave = computed(() => { + return invalid?.value || !itemInstance.value._dirty; + }); + + const saveText = computed(() => { + return isNew.value || itemInstance.value._dirty ? t('objects.save') : t('objects.saved'); + }); + + const redirectToEdit = () => { + return router.replace({ + ...route, + params: { id }, + }); + }; + + const save = async () => { + if (disabledSave.value) return; + + if (isNew.value) { + await addItem(); + } else { + await updateItem(); + } + + if (id.value) { + await redirectToEdit(); + } + }; + + async function initializeCard() { + try { + const { id } = route.params; + await setId(id); + await loadItem(); + } catch (error) { + console.error(error); + } + } + + function initialize(){ + onMounted(() => { + initializeCard(); + }); + + onUnmounted(() => { + resetState(); + }); + } + + + return { + id, + itemInstance, + isNew, + pathName, + disabledSave, + saveText, + + save, + initialize, + } +} + + diff --git a/src/composables/useCard/useCardTabs.js b/src/composables/useCard/useCardTabs.js new file mode 100644 index 000000000..a84bf3da9 --- /dev/null +++ b/src/composables/useCard/useCardTabs.js @@ -0,0 +1,28 @@ +import { computed } from 'vue'; +import { useRoute, useRouter } from 'vue-router'; + +export const useCardTabs = (tabs) => { + const router = useRouter(); + const route = useRoute(); + + const currentTab = computed(() => { + return tabs.find(({ pathName }) => route.name === pathName) || tabs[0]; + }); + + function changeTab(tab) { + const { params, query, hash } = route; + + return router.push({ + name: tab.pathName, + params, + query, + hash, + }); + } + + return { + currentTab, + + changeTab, + } +} diff --git a/src/composables/useClose/useClose.js b/src/composables/useClose/useClose.js new file mode 100644 index 000000000..eac96b5bb --- /dev/null +++ b/src/composables/useClose/useClose.js @@ -0,0 +1,13 @@ +import { useRouter } from 'vue-router'; + +// eslint-disable-next-line import/prefer-default-export +export const useClose = (name) => { + const router = useRouter(); + + function close() { + if (window.history.length === 1) window.close(); + return router.push({ name }); + } + + return { close }; +}; diff --git a/src/composables/useValidate/useValidate.js b/src/composables/useValidate/useValidate.js new file mode 100644 index 000000000..a3d5d7e6b --- /dev/null +++ b/src/composables/useValidate/useValidate.js @@ -0,0 +1,10 @@ +import { useVuelidate } from '@vuelidate/core'; + +export const useValidate = (schema, data) => { + const v$ = useVuelidate(schema, data, { $autoDirty: true }); + + return { + v$, + invalid: v$.$invalid, + }; +}