@ozdao/martyrs 0.2.563 → 0.2.565
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abac-BPl9Bmf9.js +1527 -0
- package/dist/builder.js +51 -39
- package/dist/{common.schema-GFSlNJo7.js → common.schema-DswiUXKB.js} +1 -1
- package/dist/community.server.js +48 -9
- package/dist/core.server.js +6 -4
- package/dist/{crud-C7FSTUes.js → crud-q1ye5IhV.js} +7 -7
- package/dist/events.server.js +3 -3
- package/dist/gallery.server.js +2 -2
- package/dist/inventory.server.js +4 -6
- package/dist/{main-CmjWiDVF.js → main-B9o1iBAZ.js} +1279 -1287
- package/dist/marketplace.server.js +1 -1
- package/dist/martyrs/src/components/Button/Button.vue2.js +33 -42
- package/dist/martyrs/src/components/Button/Button.vue2.js.map +1 -1
- package/dist/martyrs/src/components/EditImages/{EditImages.vue.js → EditImages.vue2.js} +2 -2
- package/dist/martyrs/src/components/EditImages/EditImages.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Feed/Feed.vue.js +1 -1
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.js +1 -1
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.js.map +1 -1
- package/dist/martyrs/src/components/Loader/Loader.vue.js +1 -2
- package/dist/martyrs/src/components/Loader/Loader.vue.js.map +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue.js → Menu.vue2.js} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Tab/{Tab.vue.js → Tab.vue2.js} +2 -2
- package/dist/martyrs/src/components/Tab/Tab.vue2.js.map +1 -0
- package/dist/martyrs/src/components/Tree/Tree.vue.js +6 -3
- package/dist/martyrs/src/components/Tree/Tree.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/auth.client.js +10 -7
- package/dist/martyrs/src/modules/auth/auth.client.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/EnterPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Invite.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ProfileBlogposts.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/ResetPassword.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js +12 -12
- package/dist/martyrs/src/modules/auth/views/components/pages/SignIn.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/SignUp.vue.js +1 -1
- package/dist/martyrs/src/modules/auth/views/router/auth.router.js +116 -0
- package/dist/martyrs/src/modules/auth/views/router/auth.router.js.map +1 -0
- package/dist/martyrs/src/modules/auth/views/router/users.router.js +180 -0
- package/dist/martyrs/src/modules/auth/views/router/users.router.js.map +1 -0
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js +3 -3
- package/dist/martyrs/src/modules/backoffice/components/partials/Sidebar.vue.js.map +1 -1
- package/dist/martyrs/src/modules/core/locales/en.js +45 -0
- package/dist/martyrs/src/modules/core/locales/en.js.map +1 -1
- package/dist/martyrs/src/modules/core/locales/ru.js +45 -0
- package/dist/martyrs/src/modules/core/locales/ru.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/classes/i18n.manager.js +9 -0
- package/dist/martyrs/src/modules/core/views/classes/i18n.manager.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/components/sections/{Filters.vue.js → Filters.vue2.js} +2 -2
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/core/views/components/sections/SectionPageTitle.vue.js +1 -1
- package/dist/martyrs/src/modules/core/views/mixins/mixins.js +1 -2
- package/dist/martyrs/src/modules/core/views/mixins/mixins.js.map +1 -1
- package/dist/martyrs/src/modules/core/views/router/addRoutes.js +6 -1
- package/dist/martyrs/src/modules/core/views/router/addRoutes.js.map +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EditEvent.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/Event.vue.js +1 -1
- package/dist/martyrs/src/modules/events/components/pages/EventsBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/gallery/components/sections/BackofficeGallery.vue.js +1 -1
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/inventory/components/pages/InventoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/pages/Marketplace.vue.js +1 -1
- package/dist/martyrs/src/modules/marketplace/views/store/marketplace.js +0 -16
- package/dist/martyrs/src/modules/marketplace/views/store/marketplace.js.map +1 -1
- package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js +4 -4
- package/dist/martyrs/src/modules/notifications/components/elements/NotificationBadge.vue.js.map +1 -1
- package/dist/martyrs/src/modules/notifications/components/pages/Notifications.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/elements/FieldSubscribeNewsletter.vue.js +3 -0
- package/dist/martyrs/src/modules/orders/components/elements/FieldSubscribeNewsletter.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/OrderCreateBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/pages/Orders.vue.js +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/blocks/CardOrganization.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/Organizations.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardCategory.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/blocks/CardProduct.vue.js +15 -2
- package/dist/martyrs/src/modules/products/components/blocks/CardProduct.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js +9 -6
- package/dist/martyrs/src/modules/products/components/pages/Categories.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +4 -3
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +11 -2
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/ProductEdit.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Products.vue.js +2 -2
- package/dist/martyrs/src/modules/products/components/sections/EditVariants.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js +11 -8
- package/dist/martyrs/src/modules/products/components/sections/SectionProduct.vue.js.map +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Gant/GanttToolbar.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/Rents.vue.js +1 -1
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js +210 -60
- package/dist/martyrs/src/modules/rents/views/components/pages/RentsEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js +3 -3
- package/dist/martyrs/src/modules/spots/components/pages/Map.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/pages/SpotEdit.vue.js +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/music.server.js +11 -12
- package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/core/utils.js +1 -1
- package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/utils.js +1 -1
- package/dist/notifications.server.js +0 -3
- package/dist/orders.server.js +5 -6
- package/dist/organizations.server.js +9 -10
- package/dist/products.server.js +27 -26
- package/dist/{queryProcessor-CBQgZycY.js → queryProcessor-C_5Iipam.js} +4 -1
- package/dist/rents.server.js +2 -3
- package/dist/spots.server.js +1 -1
- package/dist/style.css +38 -23
- package/dist/{web-cNKIl_cL.js → web-BF3ijvEr.js} +1 -1
- package/package.json +1 -1
- package/src/builder/modes/ssr.rspack.dev.js +4 -3
- package/src/builder/rspack/rspack.config.api.js +15 -4
- package/src/builder/rspack/rspack.config.base.js +3 -3
- package/src/builder/rspack/rspack.config.ssr.client.js +28 -28
- package/src/builder/templates/page.js +2 -2
- package/src/components/Button/Button.vue +50 -37
- package/src/components/FieldPhone/FieldPhone.vue +1 -1
- package/src/components/Loader/Loader.vue +1 -1
- package/src/components/Tree/Tree.vue +6 -3
- package/src/modules/PROCESS.md +0 -0
- package/src/modules/TASKS.MD +17 -0
- package/src/modules/auth/auth.client.js +11 -7
- package/src/modules/auth/views/components/pages/SignIn.vue +1 -1
- package/src/modules/auth/views/router/auth.router.js +94 -0
- package/src/modules/auth/views/router/users.router.js +153 -0
- package/src/modules/backoffice/components/partials/Sidebar.vue +7 -7
- package/src/modules/community/community.server.js +8 -0
- package/src/modules/community/policies/blog.policies.js +55 -0
- package/src/modules/community/routes/blog.routes.js +1 -1
- package/src/modules/community/routes/comments.routes.js +1 -1
- package/src/modules/community/routes/reactions.routes.js +1 -4
- package/src/modules/core/controllers/classes/abac/abac.adapter.express.js +206 -124
- package/src/modules/core/controllers/classes/abac/abac.adapter.ws.js +203 -50
- package/src/modules/core/controllers/classes/abac/abac.core.js +127 -36
- package/src/modules/core/controllers/classes/abac/abac.fields.js +144 -179
- package/src/modules/core/controllers/classes/abac/abac.js +201 -10
- package/src/modules/core/controllers/classes/abac/abac.policies.js +147 -57
- package/src/modules/core/controllers/classes/crud/crud.policies.js +5 -5
- package/src/modules/core/controllers/policies/core.policies.js +5 -2
- package/src/modules/core/controllers/utils/queryProcessor.js +4 -1
- package/src/modules/core/core.server.js +1 -0
- package/src/modules/core/locales/en.js +45 -0
- package/src/modules/core/locales/ru.js +45 -0
- package/src/modules/core/models/schemas/common.schema.js +1 -1
- package/src/modules/core/views/classes/i18n.manager.js +13 -0
- package/src/modules/core/views/components/sections/filters/FilterPrice.vue +81 -0
- package/src/modules/core/views/mixins/mixins.js +1 -2
- package/src/modules/core/views/router/addRoutes.js +6 -1
- package/src/modules/events/routes/events.routes.js +1 -1
- package/src/modules/inventory/components/pages/InventoryEdit.vue +3 -3
- package/src/modules/inventory/policies/inventory.policies.js +1 -1
- package/src/modules/inventory/routes/inventory.routes.js +1 -1
- package/src/modules/marketplace/marketplace.router.js +66 -0
- package/src/modules/marketplace/views/components/layouts/Marketplace.vue +363 -0
- package/src/modules/marketplace/views/components/pages/Catalog.vue +73 -0
- package/src/modules/marketplace/views/store/marketplace.js +0 -16
- package/src/modules/music/controllers/stream.controller.js +1 -1
- package/src/modules/music/music.server.js +1 -1
- package/src/modules/music/policies/music.policies.js +3 -2
- package/src/modules/music/router/library.router.js +26 -0
- package/src/modules/music/router/music.router.js +176 -0
- package/src/modules/notifications/components/elements/NotificationBadge.vue +5 -6
- package/src/modules/notifications/notifications.server.js +1 -3
- package/src/modules/orders/components/elements/FieldSubscribeNewsletter.vue +5 -0
- package/src/modules/orders/orders.server.js +0 -1
- package/src/modules/organizations/components/blocks/CardOrganization.vue +2 -2
- package/src/modules/organizations/components/pages/DepartmentEdit.vue +2 -2
- package/src/modules/organizations/components/pages/OrganizationEdit.vue +2 -2
- package/src/modules/organizations/policies/organizations.policies.js +12 -6
- package/src/modules/organizations/routes/organizations.routes.js +1 -3
- package/src/modules/products/components/blocks/CardCategory.vue +1 -1
- package/src/modules/products/components/blocks/CardProduct.vue +16 -2
- package/src/modules/products/components/pages/Categories.vue +9 -6
- package/src/modules/products/components/pages/CategoryEdit.vue +8 -4
- package/src/modules/products/components/pages/Product.vue +11 -5
- package/src/modules/products/components/sections/SectionProduct.vue +11 -7
- package/src/modules/products/controllers/categories.controller.js +32 -27
- package/src/modules/products/routes/categories.routes.js +1 -1
- package/src/modules/rents/controllers/routes/rents.routes.js +1 -1
- package/src/modules/rents/views/components/pages/RentsEdit.vue +208 -49
- package/src/modules/spots/components/pages/Map.vue +2 -2
- package/dist/abac-DYoheWuc.js +0 -1031
- package/dist/core.abac-DUPBnlk6.js +0 -298
- package/dist/core.logger-C3q8A9dl.js +0 -51
- package/dist/martyrs/src/components/EditImages/EditImages.vue.js.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue.js.map +0 -1
- package/dist/martyrs/src/components/Tab/Tab.vue.js.map +0 -1
- package/dist/martyrs/src/modules/auth/auth.router.js +0 -342
- package/dist/martyrs/src/modules/auth/auth.router.js.map +0 -1
- package/dist/martyrs/src/modules/core/views/components/sections/Filters.vue.js.map +0 -1
- package/src/modules/auth/auth.router.js +0 -262
- package/src/modules/core/controllers/classes/abac/v2/abac-core-fixed.js +0 -313
- package/src/modules/core/controllers/classes/abac/v2/abac-express-fixed.js +0 -276
- package/src/modules/core/controllers/classes/abac/v2/abac-fields-fixed.js +0 -425
- package/src/modules/core/controllers/classes/abac/v2/abac-main-fixed.js +0 -295
- package/src/modules/core/controllers/classes/abac/v2/abac-policies-fixed.js +0 -316
- package/src/modules/core/controllers/classes/abac/v2/abac-ws-fixed.js +0 -237
- package/src/modules/core/controllers/classes/core.abac.js +0 -310
- package/src/modules/core/controllers/classes/core.crud.js +0 -89
- package/src/modules/governance/reactcode/eslint.config.js +0 -28
|
@@ -83,17 +83,16 @@ const props = defineProps({
|
|
|
83
83
|
// Get router and notification functionality
|
|
84
84
|
const router = useRouter();
|
|
85
85
|
|
|
86
|
-
// Check if notifications module is loaded
|
|
87
|
-
const useNotifications = inject('useNotifications')
|
|
88
|
-
|
|
89
|
-
// Provide fallback values if module is not loaded
|
|
90
|
-
const { notifications, unreadCount, loading, markAllAsRead, getNotifications } = useNotifications ? useNotifications() : {
|
|
86
|
+
// Check if notifications module is loaded, provide fallback if not
|
|
87
|
+
const useNotifications = inject('useNotifications', () => ({
|
|
91
88
|
notifications: ref([]),
|
|
92
89
|
unreadCount: ref(0),
|
|
93
90
|
loading: ref(false),
|
|
94
91
|
markAllAsRead: () => {},
|
|
95
92
|
getNotifications: () => {}
|
|
96
|
-
};
|
|
93
|
+
}));
|
|
94
|
+
|
|
95
|
+
const { notifications, unreadCount, loading, markAllAsRead, getNotifications } = useNotifications();
|
|
97
96
|
|
|
98
97
|
// Local state
|
|
99
98
|
const isOpen = ref(false);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import coreabac from '@martyrs/src/modules/core/controllers/classes/core.abac.js';
|
|
2
1
|
import NotificationsController from './controllers/notifications.controller.js';
|
|
3
2
|
import NotificationLogModel from './models/notification-log.model.js';
|
|
4
3
|
import NotificationPreferenceModel from './models/notification-preference.model.js';
|
|
@@ -6,14 +5,13 @@ import NotificationModel from './models/notification.model.js';
|
|
|
6
5
|
import UserDeviceModel from './models/user-device.model.js';
|
|
7
6
|
import notificationsRoutes from './routes/notifications.routes.js';
|
|
8
7
|
import NotificationService from './services/notification.service.js';
|
|
9
|
-
|
|
8
|
+
|
|
10
9
|
function initializeNotifications(app, db, wss, origins, publicPath) {
|
|
11
10
|
// Set up models in the database object
|
|
12
11
|
db.notification = NotificationModel(db);
|
|
13
12
|
db.userDevice = UserDeviceModel(db);
|
|
14
13
|
db.notificationPreference = NotificationPreferenceModel(db);
|
|
15
14
|
db.notificationLog = NotificationLogModel(db);
|
|
16
|
-
const abac = getInstance(db);
|
|
17
15
|
// const notificationPolicies = initNotificationPolicies(abac, db);
|
|
18
16
|
|
|
19
17
|
// Initialize notification service and related background tasks only if wss is provided
|
|
@@ -49,6 +49,8 @@
|
|
|
49
49
|
<script setup>
|
|
50
50
|
import { ref, computed } from 'vue'
|
|
51
51
|
import { useI18n } from 'vue-i18n'
|
|
52
|
+
import { i18nManager } from '@martyrs/src/modules/core/views/classes/i18n.manager.js'
|
|
53
|
+
import locales from '@martyrs/src/modules/orders/locales/index.js'
|
|
52
54
|
|
|
53
55
|
import FieldBig from '@martyrs/src/components/FieldBig/FieldBig.vue'
|
|
54
56
|
import Popup from '@martyrs/src/components/Popup/Popup.vue'
|
|
@@ -64,6 +66,9 @@ import IconWhatsapp from '@martyrs/src/modules/icons/socials/whatsapp.vue'
|
|
|
64
66
|
import { useStore } from '@martyrs/src/modules/core/views/store/core.store.js'
|
|
65
67
|
import applications from '@martyrs/src/modules/orders/store/applications.js'
|
|
66
68
|
|
|
69
|
+
// Регистрируем переводы модуля при использовании компонента
|
|
70
|
+
i18nManager.register('orders', locales)
|
|
71
|
+
|
|
67
72
|
const store = useStore()
|
|
68
73
|
|
|
69
74
|
const props = defineProps({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
3
|
class="o-hidden pos-relative cursor-pointer bg-light "
|
|
4
|
-
@click="$router.push(
|
|
4
|
+
@click="$router.push('/organizations/' + organization._id)"
|
|
5
5
|
>
|
|
6
6
|
<div class="h-4r flex pos-relative">
|
|
7
7
|
|
|
@@ -281,7 +281,7 @@ async function onSubmit() {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
function redirectTo() {
|
|
284
|
-
router.push(
|
|
284
|
+
router.push('/organizations/' + route.params._id + '/members');
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
async function onDelete() {
|
|
@@ -301,7 +301,7 @@ function removeMember(member) {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
function redirectDash() {
|
|
304
|
-
router.replace(
|
|
304
|
+
router.replace('/organizations/' + route.params._id);
|
|
305
305
|
}
|
|
306
306
|
</script>
|
|
307
307
|
|
|
@@ -153,11 +153,11 @@
|
|
|
153
153
|
async function onDelete() {
|
|
154
154
|
if (route.params._id) {
|
|
155
155
|
await organization.actions.remove(route.params._id)
|
|
156
|
-
router.push(
|
|
156
|
+
router.push('/organizations/' + route.params._id)
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
function redirectTo () {
|
|
161
|
-
router.replace(
|
|
161
|
+
router.replace('/organizations/' + organization.state.current._id);
|
|
162
162
|
}
|
|
163
163
|
</script>
|
|
@@ -94,20 +94,26 @@ export default (function initializeOrganizationPolicies(abacAccessControl, db) {
|
|
|
94
94
|
// Получить организацию из контекста
|
|
95
95
|
getOrganizationId(context) {
|
|
96
96
|
const { currentResource, data } = context;
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
if (currentResource?.owner?.type === 'organization') {
|
|
99
99
|
return String(currentResource.owner.target);
|
|
100
100
|
}
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
|
|
102
|
+
// Проверяем и body и params
|
|
103
|
+
const ownerData = data?.body?.owner || data?.params?.owner;
|
|
104
|
+
if (ownerData?.type === 'organization') {
|
|
105
|
+
return String(ownerData.target);
|
|
103
106
|
}
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
|
|
108
|
+
const orgId = data?.body?.organization || data?.params?.organization;
|
|
109
|
+
if (orgId) {
|
|
110
|
+
return String(orgId);
|
|
106
111
|
}
|
|
112
|
+
|
|
107
113
|
if (currentResource?.organization) {
|
|
108
114
|
return String(currentResource.organization);
|
|
109
115
|
}
|
|
110
|
-
|
|
116
|
+
|
|
111
117
|
return null;
|
|
112
118
|
}
|
|
113
119
|
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import middlewareFactoryAuth from '@martyrs/src/modules/auth/controllers/middlewares/index.js';
|
|
2
|
-
import coreabac from '@martyrs/src/modules/core/controllers/classes/core.abac.js';
|
|
3
2
|
import controllerFactory from '../controllers/organizations.controller.js';
|
|
4
|
-
|
|
3
|
+
|
|
5
4
|
export default (function (app, db) {
|
|
6
5
|
const controller = controllerFactory(db);
|
|
7
6
|
const { authJwt } = middlewareFactoryAuth(db);
|
|
8
|
-
const abac = getInstance(db);
|
|
9
7
|
app.get(
|
|
10
8
|
'/api/organizations',
|
|
11
9
|
[
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="flex-v-center bg-light pd-small radius-small flex-column flex">
|
|
3
3
|
<div class="w-100 flex-v-center flex-nowrap gap-thin flex">
|
|
4
4
|
<img v-if="category.photo" class="i-big radius-small object-fit-contain bg-white" :src="(FILE_SERVER_URL || '') + category.photo"/>
|
|
5
|
-
<h4 class="my-handle
|
|
5
|
+
<h4 class="my-handle t-truncate w-100 w-max-100 mn-r-auto">{{category.name}}</h4>
|
|
6
6
|
|
|
7
7
|
<router-link
|
|
8
8
|
v-if="access"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<!-- Edit Button -->
|
|
11
11
|
<router-link
|
|
12
12
|
v-if="access"
|
|
13
|
-
:to="
|
|
13
|
+
:to="editPath"
|
|
14
14
|
class="
|
|
15
15
|
z-index-2
|
|
16
16
|
cursor-pointer
|
|
@@ -97,6 +97,7 @@
|
|
|
97
97
|
<script setup="props">
|
|
98
98
|
import {computed } from 'vue'
|
|
99
99
|
import { useI18n } from 'vue-i18n'
|
|
100
|
+
import { useRoute } from 'vue-router'
|
|
100
101
|
|
|
101
102
|
import IconEdit from '@martyrs/src/modules/icons/navigation/IconEdit.vue'
|
|
102
103
|
import IconShopcartAdd from '@martyrs/src/modules/icons/actions/IconShopcartAdd.vue'
|
|
@@ -106,6 +107,8 @@
|
|
|
106
107
|
|
|
107
108
|
import PlaceholderImage from '@martyrs/src/modules/icons/placeholders/PlaceholderImage.vue'
|
|
108
109
|
|
|
110
|
+
const route = useRoute()
|
|
111
|
+
|
|
109
112
|
const props = defineProps({
|
|
110
113
|
product: {
|
|
111
114
|
type: Object
|
|
@@ -122,7 +125,7 @@
|
|
|
122
125
|
default: true
|
|
123
126
|
},
|
|
124
127
|
user: {
|
|
125
|
-
type: [Object, String]
|
|
128
|
+
type: [Object, String]
|
|
126
129
|
},
|
|
127
130
|
type: {
|
|
128
131
|
type: Object
|
|
@@ -130,6 +133,17 @@
|
|
|
130
133
|
})
|
|
131
134
|
|
|
132
135
|
const { t } = useI18n()
|
|
136
|
+
|
|
137
|
+
const editPath = computed(() => {
|
|
138
|
+
if (route.meta.context === 'backoffice') {
|
|
139
|
+
return `/backoffice/products/${props.product._id}/edit`
|
|
140
|
+
}
|
|
141
|
+
if (route.meta.context === 'organization' || props.organization) {
|
|
142
|
+
const orgId = props.organization || route.params._id
|
|
143
|
+
return `/organizations/${orgId}/products/${props.product._id}/edit`
|
|
144
|
+
}
|
|
145
|
+
return `/products/${props.product._id}/edit`
|
|
146
|
+
})
|
|
133
147
|
</script>
|
|
134
148
|
|
|
135
149
|
<style lang="scss">
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
</h2>
|
|
9
9
|
|
|
10
10
|
<router-link
|
|
11
|
+
v-if="hasAccess(route.params._id, 'products', 'edit', auth.state.accesses, auth.state.access.roles)"
|
|
11
12
|
:to="{
|
|
12
13
|
name: route.meta.context === 'backoffice' ? 'BackofficeCategoryAdd' : 'Organization_CategoryAdd',
|
|
13
14
|
params: {
|
|
@@ -35,8 +36,9 @@
|
|
|
35
36
|
state: categories.state
|
|
36
37
|
}"
|
|
37
38
|
:options="{
|
|
38
|
-
|
|
39
|
-
tree: true
|
|
39
|
+
owner: route.params._id,
|
|
40
|
+
tree: true,
|
|
41
|
+
limit: 20
|
|
40
42
|
}"
|
|
41
43
|
v-model:sort="sort"
|
|
42
44
|
v-model:items="categories.state.all"
|
|
@@ -45,12 +47,13 @@
|
|
|
45
47
|
}"
|
|
46
48
|
class="rows-1 gap-thin"
|
|
47
49
|
>
|
|
48
|
-
<Tree
|
|
49
|
-
v-if="items"
|
|
50
|
-
:items="categories.state.all"
|
|
50
|
+
<Tree
|
|
51
|
+
v-if="items"
|
|
52
|
+
:items="categories.state.all"
|
|
51
53
|
:state="categories.state.all"
|
|
52
54
|
:parent-id="null"
|
|
53
|
-
|
|
55
|
+
:dragndrop="hasAccess(route.params._id, 'products', 'edit', auth.state.accesses, auth.state.access.roles)"
|
|
56
|
+
@update="updateCategoriesOrder"
|
|
54
57
|
v-slot="{ item }"
|
|
55
58
|
>
|
|
56
59
|
<CardCategory
|
|
@@ -192,7 +192,7 @@
|
|
|
192
192
|
onMounted(async () => {
|
|
193
193
|
emits('page-loading');
|
|
194
194
|
if (route.params.category) {
|
|
195
|
-
await categories.actions.read({_id: route.params.category})
|
|
195
|
+
await categories.actions.read({_id: route.params.category, owner: route.params._id})
|
|
196
196
|
} else {
|
|
197
197
|
categories.actions.clean() // Adjusted based on the new store's method to reset the category state
|
|
198
198
|
}
|
|
@@ -283,11 +283,15 @@
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
function redirectTo () {
|
|
286
|
+
const routeName = route.meta.context === 'organization'
|
|
287
|
+
? 'Organization_Categories'
|
|
288
|
+
: 'BackofficeCategories'
|
|
289
|
+
|
|
286
290
|
router.push({
|
|
287
|
-
name:
|
|
288
|
-
params: {
|
|
291
|
+
name: routeName,
|
|
292
|
+
params: {
|
|
289
293
|
_id: route.params._id
|
|
290
|
-
}
|
|
294
|
+
}
|
|
291
295
|
})
|
|
292
296
|
}
|
|
293
297
|
</script>
|
|
@@ -11,11 +11,7 @@
|
|
|
11
11
|
<!-- Edit Button -->
|
|
12
12
|
<router-link
|
|
13
13
|
v-if="hasAccess(route.params._id, 'products', 'edit', auth.state.accesses, auth.state.access.roles)"
|
|
14
|
-
:to="
|
|
15
|
-
route.params._id
|
|
16
|
-
? { name: 'Organization_ProductEdit', params: { id: route.params._id, product: product._id } }
|
|
17
|
-
: { name: 'ProductEdit', params: { product: product._id } }
|
|
18
|
-
"
|
|
14
|
+
:to="editPath"
|
|
19
15
|
class="
|
|
20
16
|
z-index-2
|
|
21
17
|
cursor-pointer
|
|
@@ -147,6 +143,16 @@ const { returnCurrency, hasAccess } = useGlobalMixins()
|
|
|
147
143
|
const product = computed(() => products.state.current)
|
|
148
144
|
const productImages = computed(() => products.state.current.images || [])
|
|
149
145
|
|
|
146
|
+
const editPath = computed(() => {
|
|
147
|
+
if (route.meta.context === 'backoffice') {
|
|
148
|
+
return `/backoffice/products/${product.value._id}/edit`
|
|
149
|
+
}
|
|
150
|
+
if (route.meta.context === 'organization') {
|
|
151
|
+
return `/organizations/${route.params._id}/products/${product.value._id}/edit`
|
|
152
|
+
}
|
|
153
|
+
return `/products/${product.value._id}/edit`
|
|
154
|
+
})
|
|
155
|
+
|
|
150
156
|
// Состояние для отслеживания текущих изображений (товара или варианта)
|
|
151
157
|
const currentImages = ref([])
|
|
152
158
|
// Выбранный вариант товара
|
|
@@ -37,13 +37,7 @@
|
|
|
37
37
|
|
|
38
38
|
<IconEdit
|
|
39
39
|
v-if="accesses && hasAccess(route.params._id, 'products', 'edit', accesses)"
|
|
40
|
-
@click="$router.push(
|
|
41
|
-
name: route.meta.context === 'backoffice' ? 'BackofficeProductEdit' : 'Organization_ProductEdit',
|
|
42
|
-
params: {
|
|
43
|
-
_id: product.owner.target,
|
|
44
|
-
product: product._id
|
|
45
|
-
}
|
|
46
|
-
})"
|
|
40
|
+
@click="$router.push(editPath)"
|
|
47
41
|
class="pos-absolute pos-t-regular pos-r-regular i-medium t-transp"
|
|
48
42
|
/>
|
|
49
43
|
|
|
@@ -183,6 +177,16 @@ const images = computed(() => {
|
|
|
183
177
|
return props.product.images
|
|
184
178
|
})
|
|
185
179
|
|
|
180
|
+
const editPath = computed(() => {
|
|
181
|
+
if (route.meta.context === 'backoffice') {
|
|
182
|
+
return `/backoffice/products/${props.product._id}/edit`
|
|
183
|
+
}
|
|
184
|
+
if (route.meta.context === 'organization') {
|
|
185
|
+
return `/organizations/${props.product.owner.target}/products/${props.product._id}/edit`
|
|
186
|
+
}
|
|
187
|
+
return `/products/${props.product._id}/edit`
|
|
188
|
+
})
|
|
189
|
+
|
|
186
190
|
const tabProduct = ref('description')
|
|
187
191
|
|
|
188
192
|
const text = {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import Cache from '@martyrs/src/modules/core/controllers/classes/core.cache.js';
|
|
2
2
|
import Logger from '@martyrs/src/modules/core/controllers/classes/core.logger.js';
|
|
3
3
|
import globalsQuery from '@martyrs/src/modules/core/controllers/utils/queryProcessor.js';
|
|
4
|
+
import coreabac from '@martyrs/src/modules/core/controllers/classes/abac/abac.js';
|
|
4
5
|
|
|
5
6
|
const controllerFactory = db => {
|
|
6
7
|
const Category = db.category;
|
|
7
8
|
const logger = new Logger(db);
|
|
8
9
|
const cache = new Cache();
|
|
10
|
+
const abac = coreabac.getInstance(db);
|
|
9
11
|
|
|
10
12
|
// Генерация уникального slug
|
|
11
13
|
const generateSlug = async (name, parentId = null) => {
|
|
@@ -174,17 +176,30 @@ const controllerFactory = db => {
|
|
|
174
176
|
const depthNum = parseInt(depth, 10);
|
|
175
177
|
const isTree = tree === 'true' || tree === true;
|
|
176
178
|
const isRoot = root === 'true' || root === true;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const cacheKey = JSON.stringify(req.query);
|
|
179
|
+
|
|
180
|
+
const cacheKey = JSON.stringify({ query: req.query, userId: req.userId });
|
|
181
181
|
const cached = await cache.get(cacheKey);
|
|
182
182
|
if (cached) return res.json(cached);
|
|
183
183
|
|
|
184
|
+
// Проверка прав на просмотр всех статусов
|
|
185
|
+
let canViewAllStatuses = false;
|
|
186
|
+
if (req.userId) {
|
|
187
|
+
const accessCheck = await abac.checkAccess({
|
|
188
|
+
user: req.userId,
|
|
189
|
+
resource: 'category',
|
|
190
|
+
action: 'read',
|
|
191
|
+
data: {
|
|
192
|
+
body: owner ? { owner: { type: 'organization', target: owner } } : {}
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
canViewAllStatuses = accessCheck.allow;
|
|
197
|
+
}
|
|
198
|
+
|
|
184
199
|
// Базовая фильтрация
|
|
185
200
|
const match = {
|
|
186
201
|
...(_id && { _id: new db.mongoose.Types.ObjectId(_id) }),
|
|
187
|
-
...(status
|
|
202
|
+
...(status !== undefined ? { status } : (canViewAllStatuses ? {} : { status: 'published' })),
|
|
188
203
|
...(search && { name: { $regex: search, $options: 'i' } }),
|
|
189
204
|
...(type && { 'owner.type': type }),
|
|
190
205
|
...(owner && { 'owner.target': new db.mongoose.Types.ObjectId(owner) }),
|
|
@@ -214,19 +229,13 @@ const controllerFactory = db => {
|
|
|
214
229
|
match.url = { $regex: '^/[^/]+$' };
|
|
215
230
|
}
|
|
216
231
|
|
|
217
|
-
console.log('🔎 Match object:', JSON.stringify(match, null, 2));
|
|
218
|
-
|
|
219
232
|
const pipeline = [
|
|
220
233
|
{ $match: match },
|
|
221
234
|
...globalsQuery.getSortingOptions(sortParam, sortOrder),
|
|
222
|
-
|
|
235
|
+
...(!isTree && (skip || limit) ? globalsQuery.getPaginationOptions(skip, limit) : []),
|
|
223
236
|
];
|
|
224
|
-
|
|
225
|
-
console.log('🔧 Pipeline:', JSON.stringify(pipeline, null, 2));
|
|
226
237
|
|
|
227
238
|
let results = await Category.aggregate(pipeline);
|
|
228
|
-
console.log('🔍 Aggregate results:', results.length, 'categories found');
|
|
229
|
-
console.log('🔍 Results URLs:', results.map(r => r.url));
|
|
230
239
|
|
|
231
240
|
// Фильтрация по глубине если указан depth > 1 и url
|
|
232
241
|
if (url && depthNum > 1) {
|
|
@@ -235,31 +244,28 @@ const controllerFactory = db => {
|
|
|
235
244
|
const catLevel = cat.url.split('/').filter(Boolean).length;
|
|
236
245
|
return cat.url === url || catLevel <= maxLevel;
|
|
237
246
|
});
|
|
238
|
-
console.log('🔍 After depth filter:', results.length, 'categories');
|
|
239
247
|
}
|
|
240
248
|
|
|
241
249
|
// Построение дерева
|
|
242
250
|
if (isTree && results.length > 0) {
|
|
243
|
-
console.log('🌳 Building tree from results');
|
|
244
251
|
results = buildTreeFromUrl(results, sortParam, sortOrder);
|
|
252
|
+
|
|
253
|
+
// Пагинация корневых элементов
|
|
254
|
+
const skipNum = parseInt(skip, 10) || 0;
|
|
255
|
+
const limitNum = parseInt(limit, 10) || 0;
|
|
256
|
+
if (limitNum > 0) {
|
|
257
|
+
results = results.slice(skipNum, skipNum + limitNum);
|
|
258
|
+
}
|
|
245
259
|
} else if (!isTree && depthNum === 1 && url && results.length > 0) {
|
|
246
|
-
console.log('📋 Processing tree=false, depth=1');
|
|
247
|
-
console.log('📋 Looking for main category with url:', url);
|
|
248
|
-
|
|
249
260
|
const mainCategory = results.find(c => c.url === url);
|
|
250
|
-
|
|
251
|
-
|
|
261
|
+
|
|
252
262
|
if (mainCategory) {
|
|
253
|
-
const children = results.filter(c =>
|
|
263
|
+
const children = results.filter(c =>
|
|
254
264
|
c.url !== url && c.url.startsWith(url + '/')
|
|
255
265
|
);
|
|
256
|
-
|
|
257
|
-
|
|
266
|
+
|
|
258
267
|
mainCategory.children = children;
|
|
259
268
|
results = [mainCategory];
|
|
260
|
-
console.log('📋 Final result with children:', results[0].url, 'children:', results[0].children.length);
|
|
261
|
-
} else {
|
|
262
|
-
console.log('❌ Main category not found in results!');
|
|
263
269
|
}
|
|
264
270
|
}
|
|
265
271
|
|
|
@@ -267,8 +273,7 @@ const controllerFactory = db => {
|
|
|
267
273
|
const tags = ['categories'];
|
|
268
274
|
if (owner) tags.push(`organization_${owner}`);
|
|
269
275
|
await cache.setWithTags(cacheKey, results, tags);
|
|
270
|
-
|
|
271
|
-
console.log('✅ Final results count:', results.length);
|
|
276
|
+
|
|
272
277
|
res.json(results);
|
|
273
278
|
} catch (err) {
|
|
274
279
|
logger.error(`Error reading categories: ${err.message}`);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import jwtFactory from '@martyrs/src/modules/auth/controllers/middlewares/authJwt.js';
|
|
2
|
-
import coreabac from '@martyrs/src/modules/core/controllers/classes/
|
|
2
|
+
import coreabac from '@martyrs/src/modules/core/controllers/classes/abac/abac.js';
|
|
3
3
|
import controllerFactory from '../controllers/categories.controller.js';
|
|
4
4
|
import verifierFactory from '../middlewares/categories.verifier.js';
|
|
5
5
|
const { getInstance } = coreabac;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import middlewareFactoryAuth from '@martyrs/src/modules/auth/controllers/middlewares/index.js';
|
|
2
|
-
import coreabac from '@martyrs/src/modules/core/controllers/classes/
|
|
2
|
+
import coreabac from '@martyrs/src/modules/core/controllers/classes/abac/abac.js';
|
|
3
3
|
import controllerFactory from '../services/rents.services.js';
|
|
4
4
|
// const middlewareFactoryRents = require('../middlewares/rent');
|
|
5
5
|
// ABAC
|