@ozdao/martyrs 0.2.482 → 0.2.484
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/{Media-JBERcJWj.js → Media-2NvSR0vE.js} +1 -1
- package/dist/{Media-p7Q8ZAQM.cjs → Media-EYG9WPI4.cjs} +1 -1
- package/dist/_virtual/_commonjsHelpers.cjs +2 -0
- package/dist/_virtual/_commonjsHelpers.cjs.map +1 -1
- package/dist/_virtual/_commonjsHelpers.js +2 -0
- package/dist/_virtual/_commonjsHelpers.js.map +1 -1
- package/dist/_virtual/index2.cjs +8 -0
- package/dist/_virtual/index2.cjs.map +1 -0
- package/dist/_virtual/index2.js +8 -0
- package/dist/_virtual/index2.js.map +1 -0
- package/dist/_virtual/index3.cjs +5 -0
- package/dist/_virtual/index3.cjs.map +1 -0
- package/dist/_virtual/index3.js +5 -0
- package/dist/_virtual/index3.js.map +1 -0
- package/dist/{main-AtCVQKF9.js → main-BT1yoKH2.js} +2871 -2502
- package/dist/main-rF15sgss.cjs +11 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs → Dropdown.vue2.cjs} +2 -2
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue2.cjs.map +1 -0
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.js → Dropdown.vue2.js} +2 -2
- package/dist/martyrs/src/components/Dropdown/{Dropdown.vue.cjs.map → Dropdown.vue2.js.map} +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs +32 -12
- package/dist/martyrs/src/components/Feed/Feed.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Feed/Feed.vue.js +48 -28
- package/dist/martyrs/src/components/Feed/Feed.vue.js.map +1 -1
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.cjs +141 -113
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.js +142 -114
- package/dist/martyrs/src/components/FieldPhone/FieldPhone.vue.js.map +1 -1
- package/dist/martyrs/src/components/Menu/{Menu.vue2.cjs → Menu.vue.cjs} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue.cjs.map +1 -0
- package/dist/martyrs/src/components/Menu/{Menu.vue2.js → Menu.vue.js} +2 -2
- package/dist/martyrs/src/components/Menu/Menu.vue.js.map +1 -0
- package/dist/martyrs/src/components/Slider/Slider.vue.cjs +21 -24
- package/dist/martyrs/src/components/Slider/Slider.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Slider/Slider.vue.js +21 -24
- package/dist/martyrs/src/components/Slider/Slider.vue.js.map +1 -1
- package/dist/martyrs/src/components/Status/Status.vue.cjs +11 -5
- package/dist/martyrs/src/components/Status/Status.vue.cjs.map +1 -1
- package/dist/martyrs/src/components/Status/Status.vue.js +13 -7
- package/dist/martyrs/src/components/Status/Status.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs +5 -3
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js +5 -3
- package/dist/martyrs/src/modules/auth/views/components/layouts/Auth.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.cjs +2 -2
- package/dist/martyrs/src/modules/auth/views/components/pages/Profile.vue.js +2 -2
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.cjs +28 -45
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.js +29 -46
- package/dist/martyrs/src/modules/auth/views/components/sections/SliderFeatures.vue.js.map +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/EnterCode.json.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/EnterCode.json.js +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/EnterPassword.json.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/EnterPassword.json.js +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/ResetPassword.json.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/ResetPassword.json.js +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/SignIn.json.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/SignIn.json.js +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/SignUp.json.cjs +1 -1
- package/dist/martyrs/src/modules/auth/views/localization/SignUp.json.js +1 -1
- package/dist/martyrs/src/modules/globals/globals.client.cjs +11 -0
- package/dist/martyrs/src/modules/globals/globals.client.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/globals.client.js +11 -0
- package/dist/martyrs/src/modules/globals/globals.client.js.map +1 -1
- package/dist/martyrs/src/modules/globals/locales/en.cjs +24 -0
- package/dist/martyrs/src/modules/globals/locales/en.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/locales/en.js +24 -0
- package/dist/martyrs/src/modules/globals/locales/en.js.map +1 -0
- package/dist/martyrs/src/modules/globals/locales/ru.cjs +24 -0
- package/dist/martyrs/src/modules/globals/locales/ru.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/locales/ru.js +24 -0
- package/dist/martyrs/src/modules/globals/locales/ru.js.map +1 -0
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs +71 -0
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js +71 -0
- package/dist/martyrs/src/modules/globals/views/classes/globals.i18n.js.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/blocks/CardHeader.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs +49 -43
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js +49 -43
- package/dist/martyrs/src/modules/globals/views/components/layouts/Client.vue.js.map +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.cjs +1 -1
- package/dist/martyrs/src/modules/globals/views/components/partials/Navigation.vue.js +1 -1
- package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs +183 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js +183 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/Filters.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.cjs +67 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.js +67 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.js.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterPrice.vue.cjs +91 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterPrice.vue.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterPrice.vue.js +91 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterPrice.vue.js.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterRange.vue2.cjs +64 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterRange.vue2.cjs.map +1 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterRange.vue2.js +64 -0
- package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterRange.vue2.js.map +1 -0
- package/dist/martyrs/src/modules/globals/views/store/globals.cjs.map +1 -1
- package/dist/martyrs/src/modules/globals/views/store/globals.js.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.cjs +52 -58
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js +52 -58
- package/dist/martyrs/src/modules/marketplace/views/components/layouts/Marketplace.vue.js.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs +4 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js +4 -1
- package/dist/martyrs/src/modules/orders/components/sections/FormDelivery.vue.js.map +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Members.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/Organization.vue.cjs +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.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/pages/OrganizationBackoffice.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/components/sections/DetailsTabSection.vue.js +1 -1
- package/dist/martyrs/src/modules/organizations/router/organizations.cjs +1 -1
- package/dist/martyrs/src/modules/organizations/router/organizations.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs +4 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js +4 -1
- package/dist/martyrs/src/modules/products/components/pages/CategoryEdit.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/LeftoverEdit.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/LeftoverEdit.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.cjs +2 -2
- package/dist/martyrs/src/modules/products/components/pages/Leftovers.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js +1 -1
- package/dist/martyrs/src/modules/products/components/pages/Product.vue.js.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsPopular.vue.cjs +2 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsPopular.vue.cjs.map +1 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsPopular.vue.js +2 -1
- package/dist/martyrs/src/modules/products/components/sections/ProductsPopular.vue.js.map +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.cjs +1 -1
- package/dist/martyrs/src/modules/spots/components/layouts/Spots.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.cjs +1 -1
- package/dist/martyrs/src/modules/wallet/views/components/pages/Wallet.vue.js +1 -1
- package/dist/martyrs/src/modules/wallet/views/localization/wallet.json.cjs +1 -1
- package/dist/martyrs/src/modules/wallet/views/localization/wallet.json.js +1 -1
- package/dist/martyrs.cjs.js +1 -1
- package/dist/martyrs.css +1 -1
- package/dist/martyrs.es.js +1 -1
- package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/core/utils.cjs +1 -1
- 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.cjs +1 -1
- package/dist/node_modules/.pnpm/qrcode@1.5.4/node_modules/qrcode/lib/renderer/utils.js +1 -1
- package/dist/node_modules/lodash.merge/index.cjs +689 -0
- package/dist/node_modules/lodash.merge/index.cjs.map +1 -0
- package/dist/node_modules/lodash.merge/index.js +689 -0
- package/dist/node_modules/lodash.merge/index.js.map +1 -0
- package/dist/style.css +103 -75
- package/package.json +1 -1
- package/src/components/Feed/Feed.vue +23 -0
- package/src/components/FieldPhone/FieldPhone.vue +337 -238
- package/src/components/Slider/Slider.vue +15 -17
- package/src/components/Status/Status.vue +10 -7
- package/src/modules/auth/views/components/layouts/Auth.vue +2 -2
- package/src/modules/auth/views/components/sections/SliderFeatures.vue +19 -73
- package/src/modules/auth/views/localization/EnterCode.json +2 -2
- package/src/modules/auth/views/localization/EnterPassword.json +2 -2
- package/src/modules/auth/views/localization/ResetPassword.json +2 -2
- package/src/modules/auth/views/localization/SignIn.json +2 -2
- package/src/modules/auth/views/localization/SignUp.json +2 -2
- package/src/modules/globals/globals.client.js +15 -1
- package/src/modules/globals/locales/en.js +21 -0
- package/src/modules/globals/locales/index.js +8 -0
- package/src/modules/globals/locales/ru.js +21 -0
- package/src/modules/globals/views/classes/globals.i18n.js +84 -0
- package/src/modules/globals/views/components/layouts/Client.vue +43 -40
- package/src/modules/globals/views/components/partials/Footer.vue +162 -162
- package/src/modules/globals/views/components/sections/Filters.vue +198 -0
- package/src/modules/globals/views/components/sections/filters/FilterOptions.vue +65 -0
- package/src/modules/globals/views/components/sections/filters/FilterPrice.vue +81 -0
- package/src/modules/globals/views/components/sections/filters/FilterRange.vue +74 -0
- package/src/modules/globals/views/store/globals.js +0 -40
- package/src/modules/marketplace/views/components/layouts/Marketplace.vue +34 -38
- package/src/modules/products/components/pages/Product.vue +1 -1
- package/src/modules/products/components/sections/ProductsPopular.vue +3 -2
- package/src/modules/wallet/views/localization/wallet.json +2 -2
- package/dist/main-B-we7C0w.cjs +0 -11
- package/dist/martyrs/src/components/Dropdown/Dropdown.vue.js.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue2.cjs.map +0 -1
- package/dist/martyrs/src/components/Menu/Menu.vue2.js.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel-autoplay@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-autoplay/esm/embla-carousel-autoplay.esm.cjs +0 -194
- package/dist/node_modules/.pnpm/embla-carousel-autoplay@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-autoplay/esm/embla-carousel-autoplay.esm.cjs.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel-autoplay@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-autoplay/esm/embla-carousel-autoplay.esm.js +0 -194
- package/dist/node_modules/.pnpm/embla-carousel-autoplay@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-autoplay/esm/embla-carousel-autoplay.esm.js.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.cjs +0 -43
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.cjs.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js +0 -43
- package/dist/node_modules/.pnpm/embla-carousel-reactive-utils@8.6.0_embla-carousel@8.6.0/node_modules/embla-carousel-reactive-utils/esm/embla-carousel-reactive-utils.esm.js.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.cjs +0 -43
- package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.cjs.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.js +0 -43
- package/dist/node_modules/.pnpm/embla-carousel-vue@8.6.0_vue@3.5.13_typescript@5.8.3_/node_modules/embla-carousel-vue/esm/embla-carousel-vue.esm.js.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.cjs +0 -1630
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.cjs.map +0 -1
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js +0 -1630
- package/dist/node_modules/.pnpm/embla-carousel@8.6.0/node_modules/embla-carousel/esm/embla-carousel.esm.js.map +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const vue = require("vue");
|
|
4
|
+
const Popup = require("../../../../../components/Popup/Popup.vue2.cjs");
|
|
5
|
+
const IconFilter = require("../../../../icons/navigation/IconFilter.vue.cjs");
|
|
6
|
+
const IconCross = require("../../../../icons/navigation/IconCross.vue.cjs");
|
|
7
|
+
const FilterOptions = require("./filters/FilterOptions.vue.cjs");
|
|
8
|
+
const FilterRange = require("./filters/FilterRange.vue2.cjs");
|
|
9
|
+
const FilterPrice = require("./filters/FilterPrice.vue.cjs");
|
|
10
|
+
;/* empty css */
|
|
11
|
+
const _hoisted_1 = { class: "flex gap-thin" };
|
|
12
|
+
const _hoisted_2 = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "ml-thin"
|
|
15
|
+
};
|
|
16
|
+
const _hoisted_3 = ["onClick"];
|
|
17
|
+
const _hoisted_4 = { class: "pd-medium bg-white radius-top-medium" };
|
|
18
|
+
const _hoisted_5 = { class: "flex justify-between align-center mb-medium" };
|
|
19
|
+
const _hoisted_6 = { class: "filters-container" };
|
|
20
|
+
const _hoisted_7 = { class: "t-h4 mb-thin" };
|
|
21
|
+
const _hoisted_8 = { class: "pd-medium bg-white radius-medium" };
|
|
22
|
+
const _hoisted_9 = { class: "t-h4 mb-thin" };
|
|
23
|
+
const _sfc_main = {
|
|
24
|
+
__name: "Filters",
|
|
25
|
+
props: /* @__PURE__ */ vue.mergeModels({
|
|
26
|
+
filters: {
|
|
27
|
+
type: Array,
|
|
28
|
+
required: true
|
|
29
|
+
}
|
|
30
|
+
}, {
|
|
31
|
+
"modelValue": {
|
|
32
|
+
type: Object,
|
|
33
|
+
default: () => ({})
|
|
34
|
+
},
|
|
35
|
+
"modelModifiers": {}
|
|
36
|
+
}),
|
|
37
|
+
emits: ["update:modelValue"],
|
|
38
|
+
setup(__props) {
|
|
39
|
+
const props = __props;
|
|
40
|
+
const model = vue.useModel(__props, "modelValue");
|
|
41
|
+
const showAllFilters = vue.ref(false);
|
|
42
|
+
const individualPopups = vue.reactive({});
|
|
43
|
+
const appliedFilters = vue.reactive({});
|
|
44
|
+
props.filters.forEach((filter) => {
|
|
45
|
+
individualPopups[props.filters.indexOf(filter)] = false;
|
|
46
|
+
if (!appliedFilters[filter.key]) {
|
|
47
|
+
appliedFilters[filter.key] = filter.defaultValue || null;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const hasActiveFilters = vue.computed(() => {
|
|
51
|
+
return Object.values(appliedFilters).some((v) => v !== null && v !== void 0);
|
|
52
|
+
});
|
|
53
|
+
const activeFiltersCount = vue.computed(() => {
|
|
54
|
+
return Object.values(appliedFilters).filter((v) => v !== null && v !== void 0).length;
|
|
55
|
+
});
|
|
56
|
+
const getFilterComponent = (type) => {
|
|
57
|
+
if (typeof type === "object") return type;
|
|
58
|
+
const components = {
|
|
59
|
+
options: FilterOptions.default,
|
|
60
|
+
range: FilterRange.default,
|
|
61
|
+
price: FilterPrice.default
|
|
62
|
+
};
|
|
63
|
+
return components[type] || FilterOptions.default;
|
|
64
|
+
};
|
|
65
|
+
const getFilterLabel = (filter) => {
|
|
66
|
+
const value = appliedFilters[filter.key];
|
|
67
|
+
if (!value) return filter.title;
|
|
68
|
+
if (Array.isArray(value) && value.length) {
|
|
69
|
+
return `${filter.title} (${value.length})`;
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === "object" && (value.min || value.max)) {
|
|
72
|
+
return `${filter.title}: ${value.min || 0}-${value.max || "∞"}`;
|
|
73
|
+
}
|
|
74
|
+
return `${filter.title}: ${value}`;
|
|
75
|
+
};
|
|
76
|
+
const getFilterActiveState = (filter) => {
|
|
77
|
+
const value = appliedFilters[filter.key];
|
|
78
|
+
return value !== null && value !== void 0;
|
|
79
|
+
};
|
|
80
|
+
const openFilter = (idx) => {
|
|
81
|
+
individualPopups[idx] = true;
|
|
82
|
+
};
|
|
83
|
+
const updateFilter = (key) => {
|
|
84
|
+
model.value = { ...appliedFilters };
|
|
85
|
+
};
|
|
86
|
+
const applyFilters = () => {
|
|
87
|
+
model.value = { ...appliedFilters };
|
|
88
|
+
showAllFilters.value = false;
|
|
89
|
+
};
|
|
90
|
+
const resetFilters = () => {
|
|
91
|
+
Object.keys(appliedFilters).forEach((key) => {
|
|
92
|
+
appliedFilters[key] = null;
|
|
93
|
+
});
|
|
94
|
+
model.value = {};
|
|
95
|
+
};
|
|
96
|
+
return (_ctx, _cache) => {
|
|
97
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
|
|
98
|
+
vue.createElementVNode("button", {
|
|
99
|
+
onClick: _cache[0] || (_cache[0] = ($event) => showAllFilters.value = true),
|
|
100
|
+
class: vue.normalizeClass(["btn-filter radius-medium pd-thin bg-light", { "bg-primary t-white": hasActiveFilters.value }])
|
|
101
|
+
}, [
|
|
102
|
+
vue.createVNode(IconFilter.default, { class: "w-1r h-auto" }),
|
|
103
|
+
activeFiltersCount.value ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_2, vue.toDisplayString(activeFiltersCount.value), 1)) : vue.createCommentVNode("", true)
|
|
104
|
+
], 2),
|
|
105
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.filters, (filter, idx) => {
|
|
106
|
+
return vue.openBlock(), vue.createElementBlock("button", {
|
|
107
|
+
key: idx,
|
|
108
|
+
onClick: () => openFilter(idx),
|
|
109
|
+
class: vue.normalizeClass(["btn-filter radius-medium pd-thin bg-light", { "bg-primary t-white": getFilterActiveState(filter) }])
|
|
110
|
+
}, vue.toDisplayString(getFilterLabel(filter)), 11, _hoisted_3);
|
|
111
|
+
}), 128)),
|
|
112
|
+
vue.createVNode(Popup.default, {
|
|
113
|
+
show: showAllFilters.value,
|
|
114
|
+
"onUpdate:show": _cache[2] || (_cache[2] = ($event) => showAllFilters.value = $event),
|
|
115
|
+
align: "bottom center",
|
|
116
|
+
class: "w-100 max-h-80vh"
|
|
117
|
+
}, {
|
|
118
|
+
default: vue.withCtx(() => [
|
|
119
|
+
vue.createElementVNode("div", _hoisted_4, [
|
|
120
|
+
vue.createElementVNode("div", _hoisted_5, [
|
|
121
|
+
_cache[3] || (_cache[3] = vue.createElementVNode("h3", { class: "t-h3" }, "Filters", -1)),
|
|
122
|
+
vue.createVNode(IconCross.default, {
|
|
123
|
+
onClick: _cache[1] || (_cache[1] = ($event) => showAllFilters.value = false),
|
|
124
|
+
class: "w-1r h-auto cursor-pointer"
|
|
125
|
+
})
|
|
126
|
+
]),
|
|
127
|
+
vue.createElementVNode("div", _hoisted_6, [
|
|
128
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.filters, (filter, idx) => {
|
|
129
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
130
|
+
key: idx,
|
|
131
|
+
class: "mb-medium"
|
|
132
|
+
}, [
|
|
133
|
+
vue.createElementVNode("h4", _hoisted_7, vue.toDisplayString(filter.title), 1),
|
|
134
|
+
(vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(getFilterComponent(filter.type)), {
|
|
135
|
+
modelValue: appliedFilters[filter.key],
|
|
136
|
+
"onUpdate:modelValue": ($event) => appliedFilters[filter.key] = $event,
|
|
137
|
+
options: filter.options,
|
|
138
|
+
config: filter.config
|
|
139
|
+
}, null, 8, ["modelValue", "onUpdate:modelValue", "options", "config"]))
|
|
140
|
+
]);
|
|
141
|
+
}), 128))
|
|
142
|
+
]),
|
|
143
|
+
vue.createElementVNode("div", { class: "flex gap-thin mt-medium" }, [
|
|
144
|
+
vue.createElementVNode("button", {
|
|
145
|
+
onClick: applyFilters,
|
|
146
|
+
class: "btn btn-primary flex-1"
|
|
147
|
+
}, "Apply"),
|
|
148
|
+
vue.createElementVNode("button", {
|
|
149
|
+
onClick: resetFilters,
|
|
150
|
+
class: "btn btn-secondary"
|
|
151
|
+
}, "Reset")
|
|
152
|
+
])
|
|
153
|
+
])
|
|
154
|
+
]),
|
|
155
|
+
_: 1
|
|
156
|
+
}, 8, ["show"]),
|
|
157
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.filters, (filter, idx) => {
|
|
158
|
+
return vue.openBlock(), vue.createBlock(Popup.default, {
|
|
159
|
+
isPopupOpen: individualPopups[idx],
|
|
160
|
+
key: `popup-${idx}`,
|
|
161
|
+
align: "bottom center",
|
|
162
|
+
class: "min-w-200"
|
|
163
|
+
}, {
|
|
164
|
+
default: vue.withCtx(() => [
|
|
165
|
+
vue.createElementVNode("div", _hoisted_8, [
|
|
166
|
+
vue.createElementVNode("h4", _hoisted_9, vue.toDisplayString(filter.title), 1),
|
|
167
|
+
(vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(getFilterComponent(filter.type)), {
|
|
168
|
+
modelValue: appliedFilters[filter.key],
|
|
169
|
+
"onUpdate:modelValue": [($event) => appliedFilters[filter.key] = $event, () => updateFilter(filter.key)],
|
|
170
|
+
options: filter.options,
|
|
171
|
+
config: filter.config
|
|
172
|
+
}, null, 8, ["modelValue", "onUpdate:modelValue", "options", "config"]))
|
|
173
|
+
])
|
|
174
|
+
]),
|
|
175
|
+
_: 2
|
|
176
|
+
}, 1032, ["isPopupOpen"]);
|
|
177
|
+
}), 128))
|
|
178
|
+
]);
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
exports.default = _sfc_main;
|
|
183
|
+
//# sourceMappingURL=Filters.vue2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Filters.vue2.cjs","sources":["../../../../../../../../src/modules/globals/views/components/sections/Filters.vue"],"sourcesContent":["<!-- FiltersBar.vue -->\n<template>\n <div class=\"flex gap-thin\">\n <!-- All Filters Button -->\n <button\n @click=\"showAllFilters = true\"\n class=\"btn-filter radius-medium pd-thin bg-light\"\n :class=\"{ 'bg-primary t-white': hasActiveFilters }\"\n >\n <IconFilter class=\"w-1r h-auto\" />\n <span v-if=\"activeFiltersCount\" class=\"ml-thin\">{{ activeFiltersCount }}</span>\n </button>\n\n <!-- Individual Filter Buttons -->\n <button\n v-for=\"(filter, idx) in filters\"\n :key=\"idx\"\n @click=\"() => openFilter(idx)\"\n class=\"btn-filter radius-medium pd-thin bg-light\"\n :class=\"{ 'bg-primary t-white': getFilterActiveState(filter) }\"\n >\n {{ getFilterLabel(filter) }}\n </button>\n\n <!-- All Filters Popup -->\n <Popup\n v-model:show=\"showAllFilters\"\n align=\"bottom center\"\n class=\"w-100 max-h-80vh\"\n >\n <div class=\"pd-medium bg-white radius-top-medium\">\n <div class=\"flex justify-between align-center mb-medium\">\n <h3 class=\"t-h3\">Filters</h3>\n <IconCross @click=\"showAllFilters = false\" class=\"w-1r h-auto cursor-pointer\" />\n </div>\n \n <div class=\"filters-container\">\n <div v-for=\"(filter, idx) in filters\" :key=\"idx\" class=\"mb-medium\">\n <h4 class=\"t-h4 mb-thin\">{{ filter.title }}</h4>\n <component\n :is=\"getFilterComponent(filter.type)\"\n v-model=\"appliedFilters[filter.key]\"\n :options=\"filter.options\"\n :config=\"filter.config\"\n />\n </div>\n </div>\n\n <div class=\"flex gap-thin mt-medium\">\n <button @click=\"applyFilters\" class=\"btn btn-primary flex-1\">Apply</button>\n <button @click=\"resetFilters\" class=\"btn btn-secondary\">Reset</button>\n </div>\n </div>\n </Popup>\n\n <!-- Individual Filter Popups -->\n <Popup\n :isPopupOpen=\"individualPopups[idx]\" \n v-for=\"(filter, idx) in filters\"\n :key=\"`popup-${idx}`\"\n align=\"bottom center\"\n class=\"min-w-200\"\n >\n <div class=\"pd-medium bg-white radius-medium\">\n <h4 class=\"t-h4 mb-thin\">{{ filter.title }}</h4>\n <component\n :is=\"getFilterComponent(filter.type)\"\n v-model=\"appliedFilters[filter.key]\"\n :options=\"filter.options\"\n :config=\"filter.config\"\n @update:modelValue=\"() => updateFilter(filter.key)\"\n />\n </div>\n </Popup>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, reactive } from 'vue'\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\nimport Select from '@martyrs/src/components/Select/Select.vue';\nimport IconFilter from '@martyrs/src/modules/icons/navigation/IconFilter.vue'\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue'\n\n// Import filter components\nimport FilterOptions from './filters/FilterOptions.vue'\nimport FilterRange from './filters/FilterRange.vue'\nimport FilterPrice from './filters/FilterPrice.vue'\n\nconst props = defineProps({\n filters: {\n type: Array,\n required: true\n }\n})\n\nconst model = defineModel({\n type: Object,\n default: () => ({})\n})\n\n// State\nconst showAllFilters = ref(false)\nconst individualPopups = reactive({})\nconst appliedFilters = reactive({})\n\n// Initialize filters\nprops.filters.forEach(filter => {\n individualPopups[props.filters.indexOf(filter)] = false\n if (!appliedFilters[filter.key]) {\n appliedFilters[filter.key] = filter.defaultValue || null\n }\n})\n\n// Computed\nconst hasActiveFilters = computed(() => {\n return Object.values(appliedFilters).some(v => v !== null && v !== undefined)\n})\n\nconst activeFiltersCount = computed(() => {\n return Object.values(appliedFilters).filter(v => v !== null && v !== undefined).length\n})\n\n// Methods\nconst getFilterComponent = (type) => {\n if (typeof type === 'object') return type\n \n const components = {\n options: FilterOptions,\n range: FilterRange,\n price: FilterPrice\n }\n \n return components[type] || FilterOptions\n}\n\nconst getFilterLabel = (filter) => {\n const value = appliedFilters[filter.key]\n if (!value) return filter.title\n \n if (Array.isArray(value) && value.length) {\n return `${filter.title} (${value.length})`\n }\n \n if (typeof value === 'object' && (value.min || value.max)) {\n return `${filter.title}: ${value.min || 0}-${value.max || '∞'}`\n }\n \n return `${filter.title}: ${value}`\n}\n\nconst getFilterActiveState = (filter) => {\n const value = appliedFilters[filter.key]\n return value !== null && value !== undefined\n}\n\nconst openFilter = (idx) => {\n individualPopups[idx] = true\n}\n\nconst updateFilter = (key) => {\n model.value = { ...appliedFilters }\n}\n\nconst applyFilters = () => {\n model.value = { ...appliedFilters }\n showAllFilters.value = false\n}\n\nconst resetFilters = () => {\n Object.keys(appliedFilters).forEach(key => {\n appliedFilters[key] = null\n })\n model.value = {}\n}\n</script>\n\n<style>\n.btn-filter {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn-filter:hover {\n opacity: 0.8;\n}\n\n.filters-container {\n max-height: 60vh;\n overflow-y: auto;\n}\n</style>"],"names":["_useModel","ref","reactive","computed","FilterOptions","FilterRange","FilterPrice"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,UAAM,QAAQ;AAOd,UAAM,QAAQA,IAAAA,SAGb,SAAA,YAAA;AAGD,UAAM,iBAAiBC,IAAG,IAAC,KAAK;AAChC,UAAM,mBAAmBC,IAAQ,SAAC,CAAE,CAAA;AACpC,UAAM,iBAAiBA,IAAQ,SAAC,CAAE,CAAA;AAGlC,UAAM,QAAQ,QAAQ,YAAU;AAC9B,uBAAiB,MAAM,QAAQ,QAAQ,MAAM,CAAC,IAAI;AAClD,UAAI,CAAC,eAAe,OAAO,GAAG,GAAG;AAC/B,uBAAe,OAAO,GAAG,IAAI,OAAO,gBAAgB;AAAA,MACxD;AAAA,IACA,CAAC;AAGD,UAAM,mBAAmBC,IAAQ,SAAC,MAAM;AACtC,aAAO,OAAO,OAAO,cAAc,EAAE,KAAK,OAAK,MAAM,QAAQ,MAAM,MAAS;AAAA,IAC9E,CAAC;AAED,UAAM,qBAAqBA,IAAQ,SAAC,MAAM;AACxC,aAAO,OAAO,OAAO,cAAc,EAAE,OAAO,OAAK,MAAM,QAAQ,MAAM,MAAS,EAAE;AAAA,IAClF,CAAC;AAGD,UAAM,qBAAqB,CAAC,SAAS;AACnC,UAAI,OAAO,SAAS,SAAU,QAAO;AAErC,YAAM,aAAa;AAAA,QACjB,SAASC,cAAa;AAAA,QACtB,OAAOC,YAAW;AAAA,QAClB,OAAOC,YAAAA;AAAAA,MACX;AAEE,aAAO,WAAW,IAAI,KAAKF,cAAAA;AAAAA,IAC7B;AAEA,UAAM,iBAAiB,CAAC,WAAW;AACjC,YAAM,QAAQ,eAAe,OAAO,GAAG;AACvC,UAAI,CAAC,MAAO,QAAO,OAAO;AAE1B,UAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ;AACxC,eAAO,GAAG,OAAO,KAAK,KAAK,MAAM,MAAM;AAAA,MAC3C;AAEE,UAAI,OAAO,UAAU,aAAa,MAAM,OAAO,MAAM,MAAM;AACzD,eAAO,GAAG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC,IAAI,MAAM,OAAO,GAAG;AAAA,MACjE;AAEE,aAAO,GAAG,OAAO,KAAK,KAAK,KAAK;AAAA,IAClC;AAEA,UAAM,uBAAuB,CAAC,WAAW;AACvC,YAAM,QAAQ,eAAe,OAAO,GAAG;AACvC,aAAO,UAAU,QAAQ,UAAU;AAAA,IACrC;AAEA,UAAM,aAAa,CAAC,QAAQ;AAC1B,uBAAiB,GAAG,IAAI;AAAA,IAC1B;AAEA,UAAM,eAAe,CAAC,QAAQ;AAC5B,YAAM,QAAQ,EAAE,GAAG,eAAc;AAAA,IACnC;AAEA,UAAM,eAAe,MAAM;AACzB,YAAM,QAAQ,EAAE,GAAG,eAAc;AACjC,qBAAe,QAAQ;AAAA,IACzB;AAEA,UAAM,eAAe,MAAM;AACzB,aAAO,KAAK,cAAc,EAAE,QAAQ,SAAO;AACzC,uBAAe,GAAG,IAAI;AAAA,MACvB,CAAA;AACD,YAAM,QAAQ,CAAA;AAAA,IAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { mergeModels, useModel, ref, reactive, computed, createElementBlock, openBlock, createElementVNode, createVNode, normalizeClass, createCommentVNode, toDisplayString, Fragment, renderList, withCtx, createBlock, resolveDynamicComponent } from "vue";
|
|
2
|
+
import _sfc_main$2 from "../../../../../components/Popup/Popup.vue2.js";
|
|
3
|
+
import _sfc_main$1 from "../../../../icons/navigation/IconFilter.vue.js";
|
|
4
|
+
import _sfc_main$3 from "../../../../icons/navigation/IconCross.vue.js";
|
|
5
|
+
import _sfc_main$6 from "./filters/FilterOptions.vue.js";
|
|
6
|
+
import _sfc_main$5 from "./filters/FilterRange.vue2.js";
|
|
7
|
+
import _sfc_main$4 from "./filters/FilterPrice.vue.js";
|
|
8
|
+
/* empty css */
|
|
9
|
+
const _hoisted_1 = { class: "flex gap-thin" };
|
|
10
|
+
const _hoisted_2 = {
|
|
11
|
+
key: 0,
|
|
12
|
+
class: "ml-thin"
|
|
13
|
+
};
|
|
14
|
+
const _hoisted_3 = ["onClick"];
|
|
15
|
+
const _hoisted_4 = { class: "pd-medium bg-white radius-top-medium" };
|
|
16
|
+
const _hoisted_5 = { class: "flex justify-between align-center mb-medium" };
|
|
17
|
+
const _hoisted_6 = { class: "filters-container" };
|
|
18
|
+
const _hoisted_7 = { class: "t-h4 mb-thin" };
|
|
19
|
+
const _hoisted_8 = { class: "pd-medium bg-white radius-medium" };
|
|
20
|
+
const _hoisted_9 = { class: "t-h4 mb-thin" };
|
|
21
|
+
const _sfc_main = {
|
|
22
|
+
__name: "Filters",
|
|
23
|
+
props: /* @__PURE__ */ mergeModels({
|
|
24
|
+
filters: {
|
|
25
|
+
type: Array,
|
|
26
|
+
required: true
|
|
27
|
+
}
|
|
28
|
+
}, {
|
|
29
|
+
"modelValue": {
|
|
30
|
+
type: Object,
|
|
31
|
+
default: () => ({})
|
|
32
|
+
},
|
|
33
|
+
"modelModifiers": {}
|
|
34
|
+
}),
|
|
35
|
+
emits: ["update:modelValue"],
|
|
36
|
+
setup(__props) {
|
|
37
|
+
const props = __props;
|
|
38
|
+
const model = useModel(__props, "modelValue");
|
|
39
|
+
const showAllFilters = ref(false);
|
|
40
|
+
const individualPopups = reactive({});
|
|
41
|
+
const appliedFilters = reactive({});
|
|
42
|
+
props.filters.forEach((filter) => {
|
|
43
|
+
individualPopups[props.filters.indexOf(filter)] = false;
|
|
44
|
+
if (!appliedFilters[filter.key]) {
|
|
45
|
+
appliedFilters[filter.key] = filter.defaultValue || null;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
const hasActiveFilters = computed(() => {
|
|
49
|
+
return Object.values(appliedFilters).some((v) => v !== null && v !== void 0);
|
|
50
|
+
});
|
|
51
|
+
const activeFiltersCount = computed(() => {
|
|
52
|
+
return Object.values(appliedFilters).filter((v) => v !== null && v !== void 0).length;
|
|
53
|
+
});
|
|
54
|
+
const getFilterComponent = (type) => {
|
|
55
|
+
if (typeof type === "object") return type;
|
|
56
|
+
const components = {
|
|
57
|
+
options: _sfc_main$6,
|
|
58
|
+
range: _sfc_main$5,
|
|
59
|
+
price: _sfc_main$4
|
|
60
|
+
};
|
|
61
|
+
return components[type] || _sfc_main$6;
|
|
62
|
+
};
|
|
63
|
+
const getFilterLabel = (filter) => {
|
|
64
|
+
const value = appliedFilters[filter.key];
|
|
65
|
+
if (!value) return filter.title;
|
|
66
|
+
if (Array.isArray(value) && value.length) {
|
|
67
|
+
return `${filter.title} (${value.length})`;
|
|
68
|
+
}
|
|
69
|
+
if (typeof value === "object" && (value.min || value.max)) {
|
|
70
|
+
return `${filter.title}: ${value.min || 0}-${value.max || "∞"}`;
|
|
71
|
+
}
|
|
72
|
+
return `${filter.title}: ${value}`;
|
|
73
|
+
};
|
|
74
|
+
const getFilterActiveState = (filter) => {
|
|
75
|
+
const value = appliedFilters[filter.key];
|
|
76
|
+
return value !== null && value !== void 0;
|
|
77
|
+
};
|
|
78
|
+
const openFilter = (idx) => {
|
|
79
|
+
individualPopups[idx] = true;
|
|
80
|
+
};
|
|
81
|
+
const updateFilter = (key) => {
|
|
82
|
+
model.value = { ...appliedFilters };
|
|
83
|
+
};
|
|
84
|
+
const applyFilters = () => {
|
|
85
|
+
model.value = { ...appliedFilters };
|
|
86
|
+
showAllFilters.value = false;
|
|
87
|
+
};
|
|
88
|
+
const resetFilters = () => {
|
|
89
|
+
Object.keys(appliedFilters).forEach((key) => {
|
|
90
|
+
appliedFilters[key] = null;
|
|
91
|
+
});
|
|
92
|
+
model.value = {};
|
|
93
|
+
};
|
|
94
|
+
return (_ctx, _cache) => {
|
|
95
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
96
|
+
createElementVNode("button", {
|
|
97
|
+
onClick: _cache[0] || (_cache[0] = ($event) => showAllFilters.value = true),
|
|
98
|
+
class: normalizeClass(["btn-filter radius-medium pd-thin bg-light", { "bg-primary t-white": hasActiveFilters.value }])
|
|
99
|
+
}, [
|
|
100
|
+
createVNode(_sfc_main$1, { class: "w-1r h-auto" }),
|
|
101
|
+
activeFiltersCount.value ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(activeFiltersCount.value), 1)) : createCommentVNode("", true)
|
|
102
|
+
], 2),
|
|
103
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.filters, (filter, idx) => {
|
|
104
|
+
return openBlock(), createElementBlock("button", {
|
|
105
|
+
key: idx,
|
|
106
|
+
onClick: () => openFilter(idx),
|
|
107
|
+
class: normalizeClass(["btn-filter radius-medium pd-thin bg-light", { "bg-primary t-white": getFilterActiveState(filter) }])
|
|
108
|
+
}, toDisplayString(getFilterLabel(filter)), 11, _hoisted_3);
|
|
109
|
+
}), 128)),
|
|
110
|
+
createVNode(_sfc_main$2, {
|
|
111
|
+
show: showAllFilters.value,
|
|
112
|
+
"onUpdate:show": _cache[2] || (_cache[2] = ($event) => showAllFilters.value = $event),
|
|
113
|
+
align: "bottom center",
|
|
114
|
+
class: "w-100 max-h-80vh"
|
|
115
|
+
}, {
|
|
116
|
+
default: withCtx(() => [
|
|
117
|
+
createElementVNode("div", _hoisted_4, [
|
|
118
|
+
createElementVNode("div", _hoisted_5, [
|
|
119
|
+
_cache[3] || (_cache[3] = createElementVNode("h3", { class: "t-h3" }, "Filters", -1)),
|
|
120
|
+
createVNode(_sfc_main$3, {
|
|
121
|
+
onClick: _cache[1] || (_cache[1] = ($event) => showAllFilters.value = false),
|
|
122
|
+
class: "w-1r h-auto cursor-pointer"
|
|
123
|
+
})
|
|
124
|
+
]),
|
|
125
|
+
createElementVNode("div", _hoisted_6, [
|
|
126
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.filters, (filter, idx) => {
|
|
127
|
+
return openBlock(), createElementBlock("div", {
|
|
128
|
+
key: idx,
|
|
129
|
+
class: "mb-medium"
|
|
130
|
+
}, [
|
|
131
|
+
createElementVNode("h4", _hoisted_7, toDisplayString(filter.title), 1),
|
|
132
|
+
(openBlock(), createBlock(resolveDynamicComponent(getFilterComponent(filter.type)), {
|
|
133
|
+
modelValue: appliedFilters[filter.key],
|
|
134
|
+
"onUpdate:modelValue": ($event) => appliedFilters[filter.key] = $event,
|
|
135
|
+
options: filter.options,
|
|
136
|
+
config: filter.config
|
|
137
|
+
}, null, 8, ["modelValue", "onUpdate:modelValue", "options", "config"]))
|
|
138
|
+
]);
|
|
139
|
+
}), 128))
|
|
140
|
+
]),
|
|
141
|
+
createElementVNode("div", { class: "flex gap-thin mt-medium" }, [
|
|
142
|
+
createElementVNode("button", {
|
|
143
|
+
onClick: applyFilters,
|
|
144
|
+
class: "btn btn-primary flex-1"
|
|
145
|
+
}, "Apply"),
|
|
146
|
+
createElementVNode("button", {
|
|
147
|
+
onClick: resetFilters,
|
|
148
|
+
class: "btn btn-secondary"
|
|
149
|
+
}, "Reset")
|
|
150
|
+
])
|
|
151
|
+
])
|
|
152
|
+
]),
|
|
153
|
+
_: 1
|
|
154
|
+
}, 8, ["show"]),
|
|
155
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.filters, (filter, idx) => {
|
|
156
|
+
return openBlock(), createBlock(_sfc_main$2, {
|
|
157
|
+
isPopupOpen: individualPopups[idx],
|
|
158
|
+
key: `popup-${idx}`,
|
|
159
|
+
align: "bottom center",
|
|
160
|
+
class: "min-w-200"
|
|
161
|
+
}, {
|
|
162
|
+
default: withCtx(() => [
|
|
163
|
+
createElementVNode("div", _hoisted_8, [
|
|
164
|
+
createElementVNode("h4", _hoisted_9, toDisplayString(filter.title), 1),
|
|
165
|
+
(openBlock(), createBlock(resolveDynamicComponent(getFilterComponent(filter.type)), {
|
|
166
|
+
modelValue: appliedFilters[filter.key],
|
|
167
|
+
"onUpdate:modelValue": [($event) => appliedFilters[filter.key] = $event, () => updateFilter(filter.key)],
|
|
168
|
+
options: filter.options,
|
|
169
|
+
config: filter.config
|
|
170
|
+
}, null, 8, ["modelValue", "onUpdate:modelValue", "options", "config"]))
|
|
171
|
+
])
|
|
172
|
+
]),
|
|
173
|
+
_: 2
|
|
174
|
+
}, 1032, ["isPopupOpen"]);
|
|
175
|
+
}), 128))
|
|
176
|
+
]);
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
export {
|
|
181
|
+
_sfc_main as default
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=Filters.vue2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Filters.vue2.js","sources":["../../../../../../../../src/modules/globals/views/components/sections/Filters.vue"],"sourcesContent":["<!-- FiltersBar.vue -->\n<template>\n <div class=\"flex gap-thin\">\n <!-- All Filters Button -->\n <button\n @click=\"showAllFilters = true\"\n class=\"btn-filter radius-medium pd-thin bg-light\"\n :class=\"{ 'bg-primary t-white': hasActiveFilters }\"\n >\n <IconFilter class=\"w-1r h-auto\" />\n <span v-if=\"activeFiltersCount\" class=\"ml-thin\">{{ activeFiltersCount }}</span>\n </button>\n\n <!-- Individual Filter Buttons -->\n <button\n v-for=\"(filter, idx) in filters\"\n :key=\"idx\"\n @click=\"() => openFilter(idx)\"\n class=\"btn-filter radius-medium pd-thin bg-light\"\n :class=\"{ 'bg-primary t-white': getFilterActiveState(filter) }\"\n >\n {{ getFilterLabel(filter) }}\n </button>\n\n <!-- All Filters Popup -->\n <Popup\n v-model:show=\"showAllFilters\"\n align=\"bottom center\"\n class=\"w-100 max-h-80vh\"\n >\n <div class=\"pd-medium bg-white radius-top-medium\">\n <div class=\"flex justify-between align-center mb-medium\">\n <h3 class=\"t-h3\">Filters</h3>\n <IconCross @click=\"showAllFilters = false\" class=\"w-1r h-auto cursor-pointer\" />\n </div>\n \n <div class=\"filters-container\">\n <div v-for=\"(filter, idx) in filters\" :key=\"idx\" class=\"mb-medium\">\n <h4 class=\"t-h4 mb-thin\">{{ filter.title }}</h4>\n <component\n :is=\"getFilterComponent(filter.type)\"\n v-model=\"appliedFilters[filter.key]\"\n :options=\"filter.options\"\n :config=\"filter.config\"\n />\n </div>\n </div>\n\n <div class=\"flex gap-thin mt-medium\">\n <button @click=\"applyFilters\" class=\"btn btn-primary flex-1\">Apply</button>\n <button @click=\"resetFilters\" class=\"btn btn-secondary\">Reset</button>\n </div>\n </div>\n </Popup>\n\n <!-- Individual Filter Popups -->\n <Popup\n :isPopupOpen=\"individualPopups[idx]\" \n v-for=\"(filter, idx) in filters\"\n :key=\"`popup-${idx}`\"\n align=\"bottom center\"\n class=\"min-w-200\"\n >\n <div class=\"pd-medium bg-white radius-medium\">\n <h4 class=\"t-h4 mb-thin\">{{ filter.title }}</h4>\n <component\n :is=\"getFilterComponent(filter.type)\"\n v-model=\"appliedFilters[filter.key]\"\n :options=\"filter.options\"\n :config=\"filter.config\"\n @update:modelValue=\"() => updateFilter(filter.key)\"\n />\n </div>\n </Popup>\n </div>\n</template>\n\n<script setup>\nimport { ref, computed, reactive } from 'vue'\nimport Field from '@martyrs/src/components/Field/Field.vue';\nimport Popup from '@martyrs/src/components/Popup/Popup.vue';\nimport Select from '@martyrs/src/components/Select/Select.vue';\nimport IconFilter from '@martyrs/src/modules/icons/navigation/IconFilter.vue'\nimport IconCross from '@martyrs/src/modules/icons/navigation/IconCross.vue'\n\n// Import filter components\nimport FilterOptions from './filters/FilterOptions.vue'\nimport FilterRange from './filters/FilterRange.vue'\nimport FilterPrice from './filters/FilterPrice.vue'\n\nconst props = defineProps({\n filters: {\n type: Array,\n required: true\n }\n})\n\nconst model = defineModel({\n type: Object,\n default: () => ({})\n})\n\n// State\nconst showAllFilters = ref(false)\nconst individualPopups = reactive({})\nconst appliedFilters = reactive({})\n\n// Initialize filters\nprops.filters.forEach(filter => {\n individualPopups[props.filters.indexOf(filter)] = false\n if (!appliedFilters[filter.key]) {\n appliedFilters[filter.key] = filter.defaultValue || null\n }\n})\n\n// Computed\nconst hasActiveFilters = computed(() => {\n return Object.values(appliedFilters).some(v => v !== null && v !== undefined)\n})\n\nconst activeFiltersCount = computed(() => {\n return Object.values(appliedFilters).filter(v => v !== null && v !== undefined).length\n})\n\n// Methods\nconst getFilterComponent = (type) => {\n if (typeof type === 'object') return type\n \n const components = {\n options: FilterOptions,\n range: FilterRange,\n price: FilterPrice\n }\n \n return components[type] || FilterOptions\n}\n\nconst getFilterLabel = (filter) => {\n const value = appliedFilters[filter.key]\n if (!value) return filter.title\n \n if (Array.isArray(value) && value.length) {\n return `${filter.title} (${value.length})`\n }\n \n if (typeof value === 'object' && (value.min || value.max)) {\n return `${filter.title}: ${value.min || 0}-${value.max || '∞'}`\n }\n \n return `${filter.title}: ${value}`\n}\n\nconst getFilterActiveState = (filter) => {\n const value = appliedFilters[filter.key]\n return value !== null && value !== undefined\n}\n\nconst openFilter = (idx) => {\n individualPopups[idx] = true\n}\n\nconst updateFilter = (key) => {\n model.value = { ...appliedFilters }\n}\n\nconst applyFilters = () => {\n model.value = { ...appliedFilters }\n showAllFilters.value = false\n}\n\nconst resetFilters = () => {\n Object.keys(appliedFilters).forEach(key => {\n appliedFilters[key] = null\n })\n model.value = {}\n}\n</script>\n\n<style>\n.btn-filter {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n border: none;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n}\n\n.btn-filter:hover {\n opacity: 0.8;\n}\n\n.filters-container {\n max-height: 60vh;\n overflow-y: auto;\n}\n</style>"],"names":["_useModel","FilterOptions","FilterRange","FilterPrice"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0FA,UAAM,QAAQ;AAOd,UAAM,QAAQA,SAGb,SAAA,YAAA;AAGD,UAAM,iBAAiB,IAAI,KAAK;AAChC,UAAM,mBAAmB,SAAS,CAAE,CAAA;AACpC,UAAM,iBAAiB,SAAS,CAAE,CAAA;AAGlC,UAAM,QAAQ,QAAQ,YAAU;AAC9B,uBAAiB,MAAM,QAAQ,QAAQ,MAAM,CAAC,IAAI;AAClD,UAAI,CAAC,eAAe,OAAO,GAAG,GAAG;AAC/B,uBAAe,OAAO,GAAG,IAAI,OAAO,gBAAgB;AAAA,MACxD;AAAA,IACA,CAAC;AAGD,UAAM,mBAAmB,SAAS,MAAM;AACtC,aAAO,OAAO,OAAO,cAAc,EAAE,KAAK,OAAK,MAAM,QAAQ,MAAM,MAAS;AAAA,IAC9E,CAAC;AAED,UAAM,qBAAqB,SAAS,MAAM;AACxC,aAAO,OAAO,OAAO,cAAc,EAAE,OAAO,OAAK,MAAM,QAAQ,MAAM,MAAS,EAAE;AAAA,IAClF,CAAC;AAGD,UAAM,qBAAqB,CAAC,SAAS;AACnC,UAAI,OAAO,SAAS,SAAU,QAAO;AAErC,YAAM,aAAa;AAAA,QACjB,SAASC;AAAAA,QACT,OAAOC;AAAAA,QACP,OAAOC;AAAAA,MACX;AAEE,aAAO,WAAW,IAAI,KAAKF;AAAAA,IAC7B;AAEA,UAAM,iBAAiB,CAAC,WAAW;AACjC,YAAM,QAAQ,eAAe,OAAO,GAAG;AACvC,UAAI,CAAC,MAAO,QAAO,OAAO;AAE1B,UAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ;AACxC,eAAO,GAAG,OAAO,KAAK,KAAK,MAAM,MAAM;AAAA,MAC3C;AAEE,UAAI,OAAO,UAAU,aAAa,MAAM,OAAO,MAAM,MAAM;AACzD,eAAO,GAAG,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC,IAAI,MAAM,OAAO,GAAG;AAAA,MACjE;AAEE,aAAO,GAAG,OAAO,KAAK,KAAK,KAAK;AAAA,IAClC;AAEA,UAAM,uBAAuB,CAAC,WAAW;AACvC,YAAM,QAAQ,eAAe,OAAO,GAAG;AACvC,aAAO,UAAU,QAAQ,UAAU;AAAA,IACrC;AAEA,UAAM,aAAa,CAAC,QAAQ;AAC1B,uBAAiB,GAAG,IAAI;AAAA,IAC1B;AAEA,UAAM,eAAe,CAAC,QAAQ;AAC5B,YAAM,QAAQ,EAAE,GAAG,eAAc;AAAA,IACnC;AAEA,UAAM,eAAe,MAAM;AACzB,YAAM,QAAQ,EAAE,GAAG,eAAc;AACjC,qBAAe,QAAQ;AAAA,IACzB;AAEA,UAAM,eAAe,MAAM;AACzB,aAAO,KAAK,cAAc,EAAE,QAAQ,SAAO;AACzC,uBAAe,GAAG,IAAI;AAAA,MACvB,CAAA;AACD,YAAM,QAAQ,CAAA;AAAA,IAChB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.cjs
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const vue = require("vue");
|
|
4
|
+
const Field = require("../../../../../../components/Field/Field.vue.cjs");
|
|
5
|
+
const _hoisted_1 = { class: "filter-options" };
|
|
6
|
+
const _hoisted_2 = ["onClick"];
|
|
7
|
+
const _sfc_main = {
|
|
8
|
+
__name: "FilterOptions",
|
|
9
|
+
props: /* @__PURE__ */ vue.mergeModels({
|
|
10
|
+
options: {
|
|
11
|
+
type: Array,
|
|
12
|
+
required: true,
|
|
13
|
+
default: () => []
|
|
14
|
+
}
|
|
15
|
+
}, {
|
|
16
|
+
"modelValue": {
|
|
17
|
+
type: Array,
|
|
18
|
+
default: () => []
|
|
19
|
+
},
|
|
20
|
+
"modelModifiers": {}
|
|
21
|
+
}),
|
|
22
|
+
emits: ["update:modelValue"],
|
|
23
|
+
setup(__props) {
|
|
24
|
+
const props = __props;
|
|
25
|
+
const model = vue.useModel(__props, "modelValue");
|
|
26
|
+
const checkboxStates = vue.ref({});
|
|
27
|
+
props.options.forEach((option) => {
|
|
28
|
+
checkboxStates.value[option.value] = model.value.includes(option.value);
|
|
29
|
+
});
|
|
30
|
+
vue.watch(model, (newVal) => {
|
|
31
|
+
props.options.forEach((option) => {
|
|
32
|
+
checkboxStates.value[option.value] = newVal.includes(option.value);
|
|
33
|
+
});
|
|
34
|
+
}, { deep: true });
|
|
35
|
+
vue.watch(checkboxStates, (states) => {
|
|
36
|
+
const selected = [];
|
|
37
|
+
Object.entries(states).forEach(([value, checked]) => {
|
|
38
|
+
if (checked) selected.push(value);
|
|
39
|
+
});
|
|
40
|
+
model.value = selected;
|
|
41
|
+
}, { deep: true });
|
|
42
|
+
const toggleOption = (value) => {
|
|
43
|
+
checkboxStates.value[value] = !checkboxStates.value[value];
|
|
44
|
+
};
|
|
45
|
+
return (_ctx, _cache) => {
|
|
46
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
|
|
47
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.options, (option) => {
|
|
48
|
+
return vue.openBlock(), vue.createElementBlock("div", {
|
|
49
|
+
key: option.value,
|
|
50
|
+
class: "flex align-center gap-thin pd-thin cursor-pointer hover-bg-light radius-small",
|
|
51
|
+
onClick: ($event) => toggleOption(option.value)
|
|
52
|
+
}, [
|
|
53
|
+
vue.createVNode(Field.default, {
|
|
54
|
+
type: "checkbox",
|
|
55
|
+
field: checkboxStates.value[option.value],
|
|
56
|
+
"onUpdate:field": ($event) => checkboxStates.value[option.value] = $event,
|
|
57
|
+
class: "mr-thin"
|
|
58
|
+
}, null, 8, ["field", "onUpdate:field"]),
|
|
59
|
+
vue.createElementVNode("span", null, vue.toDisplayString(option.label), 1)
|
|
60
|
+
], 8, _hoisted_2);
|
|
61
|
+
}), 128))
|
|
62
|
+
]);
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
exports.default = _sfc_main;
|
|
67
|
+
//# sourceMappingURL=FilterOptions.vue.cjs.map
|
package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterOptions.vue.cjs","sources":["../../../../../../../../../src/modules/globals/views/components/sections/filters/FilterOptions.vue"],"sourcesContent":["<!-- filters/FilterOptions.vue -->\n<template>\n <div class=\"filter-options\">\n <div\n v-for=\"option in options\"\n :key=\"option.value\"\n class=\"flex align-center gap-thin pd-thin cursor-pointer hover-bg-light radius-small\"\n @click=\"toggleOption(option.value)\"\n >\n <Field\n type=\"checkbox\"\n v-model:field=\"checkboxStates[option.value]\"\n class=\"mr-thin\"\n />\n <span>{{ option.label }}</span>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, watch } from 'vue'\nimport Field from '@martyrs/src/components/Field/Field.vue';\n\n\nconst props = defineProps({\n options: {\n type: Array,\n required: true,\n default: () => []\n }\n})\n\nconst model = defineModel({\n type: Array,\n default: () => []\n})\n\n// Создаем объект для хранения состояний чекбоксов\nconst checkboxStates = ref({})\n\n// Инициализация состояний\nprops.options.forEach(option => {\n checkboxStates.value[option.value] = model.value.includes(option.value)\n})\n\n// Следим за изменениями модели\nwatch(model, (newVal) => {\n props.options.forEach(option => {\n checkboxStates.value[option.value] = newVal.includes(option.value)\n })\n}, { deep: true })\n\n// Обновляем модель при изменении чекбоксов\nwatch(checkboxStates, (states) => {\n const selected = []\n Object.entries(states).forEach(([value, checked]) => {\n if (checked) selected.push(value)\n })\n model.value = selected\n}, { deep: true })\n\nconst toggleOption = (value) => {\n checkboxStates.value[value] = !checkboxStates.value[value]\n}\n</script>"],"names":["_useModel","ref","watch"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAwBA,UAAM,QAAQ;AAQd,UAAM,QAAQA,IAAAA,SAGb,SAAA,YAAA;AAGD,UAAM,iBAAiBC,IAAG,IAAC,CAAE,CAAA;AAG7B,UAAM,QAAQ,QAAQ,YAAU;AAC9B,qBAAe,MAAM,OAAO,KAAK,IAAI,MAAM,MAAM,SAAS,OAAO,KAAK;AAAA,IACxE,CAAC;AAGDC,QAAAA,MAAM,OAAO,CAAC,WAAW;AACvB,YAAM,QAAQ,QAAQ,YAAU;AAC9B,uBAAe,MAAM,OAAO,KAAK,IAAI,OAAO,SAAS,OAAO,KAAK;AAAA,MAClE,CAAA;AAAA,IACH,GAAG,EAAE,MAAM,KAAM,CAAA;AAGjBA,QAAAA,MAAM,gBAAgB,CAAC,WAAW;AAChC,YAAM,WAAW,CAAA;AACjB,aAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,OAAO,MAAM;AACnD,YAAI,QAAS,UAAS,KAAK,KAAK;AAAA,MACjC,CAAA;AACD,YAAM,QAAQ;AAAA,IAChB,GAAG,EAAE,MAAM,KAAM,CAAA;AAEjB,UAAM,eAAe,CAAC,UAAU;AAC9B,qBAAe,MAAM,KAAK,IAAI,CAAC,eAAe,MAAM,KAAK;AAAA,IAC3D;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { mergeModels, useModel, ref, watch, createElementBlock, openBlock, Fragment, renderList, createVNode, createElementVNode, toDisplayString } from "vue";
|
|
2
|
+
import Field from "../../../../../../components/Field/Field.vue.js";
|
|
3
|
+
const _hoisted_1 = { class: "filter-options" };
|
|
4
|
+
const _hoisted_2 = ["onClick"];
|
|
5
|
+
const _sfc_main = {
|
|
6
|
+
__name: "FilterOptions",
|
|
7
|
+
props: /* @__PURE__ */ mergeModels({
|
|
8
|
+
options: {
|
|
9
|
+
type: Array,
|
|
10
|
+
required: true,
|
|
11
|
+
default: () => []
|
|
12
|
+
}
|
|
13
|
+
}, {
|
|
14
|
+
"modelValue": {
|
|
15
|
+
type: Array,
|
|
16
|
+
default: () => []
|
|
17
|
+
},
|
|
18
|
+
"modelModifiers": {}
|
|
19
|
+
}),
|
|
20
|
+
emits: ["update:modelValue"],
|
|
21
|
+
setup(__props) {
|
|
22
|
+
const props = __props;
|
|
23
|
+
const model = useModel(__props, "modelValue");
|
|
24
|
+
const checkboxStates = ref({});
|
|
25
|
+
props.options.forEach((option) => {
|
|
26
|
+
checkboxStates.value[option.value] = model.value.includes(option.value);
|
|
27
|
+
});
|
|
28
|
+
watch(model, (newVal) => {
|
|
29
|
+
props.options.forEach((option) => {
|
|
30
|
+
checkboxStates.value[option.value] = newVal.includes(option.value);
|
|
31
|
+
});
|
|
32
|
+
}, { deep: true });
|
|
33
|
+
watch(checkboxStates, (states) => {
|
|
34
|
+
const selected = [];
|
|
35
|
+
Object.entries(states).forEach(([value, checked]) => {
|
|
36
|
+
if (checked) selected.push(value);
|
|
37
|
+
});
|
|
38
|
+
model.value = selected;
|
|
39
|
+
}, { deep: true });
|
|
40
|
+
const toggleOption = (value) => {
|
|
41
|
+
checkboxStates.value[value] = !checkboxStates.value[value];
|
|
42
|
+
};
|
|
43
|
+
return (_ctx, _cache) => {
|
|
44
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
45
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option) => {
|
|
46
|
+
return openBlock(), createElementBlock("div", {
|
|
47
|
+
key: option.value,
|
|
48
|
+
class: "flex align-center gap-thin pd-thin cursor-pointer hover-bg-light radius-small",
|
|
49
|
+
onClick: ($event) => toggleOption(option.value)
|
|
50
|
+
}, [
|
|
51
|
+
createVNode(Field, {
|
|
52
|
+
type: "checkbox",
|
|
53
|
+
field: checkboxStates.value[option.value],
|
|
54
|
+
"onUpdate:field": ($event) => checkboxStates.value[option.value] = $event,
|
|
55
|
+
class: "mr-thin"
|
|
56
|
+
}, null, 8, ["field", "onUpdate:field"]),
|
|
57
|
+
createElementVNode("span", null, toDisplayString(option.label), 1)
|
|
58
|
+
], 8, _hoisted_2);
|
|
59
|
+
}), 128))
|
|
60
|
+
]);
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
export {
|
|
65
|
+
_sfc_main as default
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=FilterOptions.vue.js.map
|
package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterOptions.vue.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterOptions.vue.js","sources":["../../../../../../../../../src/modules/globals/views/components/sections/filters/FilterOptions.vue"],"sourcesContent":["<!-- filters/FilterOptions.vue -->\n<template>\n <div class=\"filter-options\">\n <div\n v-for=\"option in options\"\n :key=\"option.value\"\n class=\"flex align-center gap-thin pd-thin cursor-pointer hover-bg-light radius-small\"\n @click=\"toggleOption(option.value)\"\n >\n <Field\n type=\"checkbox\"\n v-model:field=\"checkboxStates[option.value]\"\n class=\"mr-thin\"\n />\n <span>{{ option.label }}</span>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, watch } from 'vue'\nimport Field from '@martyrs/src/components/Field/Field.vue';\n\n\nconst props = defineProps({\n options: {\n type: Array,\n required: true,\n default: () => []\n }\n})\n\nconst model = defineModel({\n type: Array,\n default: () => []\n})\n\n// Создаем объект для хранения состояний чекбоксов\nconst checkboxStates = ref({})\n\n// Инициализация состояний\nprops.options.forEach(option => {\n checkboxStates.value[option.value] = model.value.includes(option.value)\n})\n\n// Следим за изменениями модели\nwatch(model, (newVal) => {\n props.options.forEach(option => {\n checkboxStates.value[option.value] = newVal.includes(option.value)\n })\n}, { deep: true })\n\n// Обновляем модель при изменении чекбоксов\nwatch(checkboxStates, (states) => {\n const selected = []\n Object.entries(states).forEach(([value, checked]) => {\n if (checked) selected.push(value)\n })\n model.value = selected\n}, { deep: true })\n\nconst toggleOption = (value) => {\n checkboxStates.value[value] = !checkboxStates.value[value]\n}\n</script>"],"names":["_useModel"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,UAAM,QAAQ;AAQd,UAAM,QAAQA,SAGb,SAAA,YAAA;AAGD,UAAM,iBAAiB,IAAI,CAAE,CAAA;AAG7B,UAAM,QAAQ,QAAQ,YAAU;AAC9B,qBAAe,MAAM,OAAO,KAAK,IAAI,MAAM,MAAM,SAAS,OAAO,KAAK;AAAA,IACxE,CAAC;AAGD,UAAM,OAAO,CAAC,WAAW;AACvB,YAAM,QAAQ,QAAQ,YAAU;AAC9B,uBAAe,MAAM,OAAO,KAAK,IAAI,OAAO,SAAS,OAAO,KAAK;AAAA,MAClE,CAAA;AAAA,IACH,GAAG,EAAE,MAAM,KAAM,CAAA;AAGjB,UAAM,gBAAgB,CAAC,WAAW;AAChC,YAAM,WAAW,CAAA;AACjB,aAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,OAAO,MAAM;AACnD,YAAI,QAAS,UAAS,KAAK,KAAK;AAAA,MACjC,CAAA;AACD,YAAM,QAAQ;AAAA,IAChB,GAAG,EAAE,MAAM,KAAM,CAAA;AAEjB,UAAM,eAAe,CAAC,UAAU;AAC9B,qBAAe,MAAM,KAAK,IAAI,CAAC,eAAe,MAAM,KAAK;AAAA,IAC3D;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterPrice.vue.cjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const vue = require("vue");
|
|
4
|
+
const Field = require("../../../../../../components/Field/Field.vue.cjs");
|
|
5
|
+
const _hoisted_1 = { class: "filter-price" };
|
|
6
|
+
const _hoisted_2 = { class: "flex gap-thin align-center" };
|
|
7
|
+
const _hoisted_3 = {
|
|
8
|
+
key: 0,
|
|
9
|
+
class: "mt-thin"
|
|
10
|
+
};
|
|
11
|
+
const _hoisted_4 = ["onClick"];
|
|
12
|
+
const _sfc_main = {
|
|
13
|
+
__name: "FilterPrice",
|
|
14
|
+
props: /* @__PURE__ */ vue.mergeModels({
|
|
15
|
+
config: {
|
|
16
|
+
type: Object,
|
|
17
|
+
default: () => ({})
|
|
18
|
+
}
|
|
19
|
+
}, {
|
|
20
|
+
"modelValue": {
|
|
21
|
+
type: Object,
|
|
22
|
+
default: () => ({ min: null, max: null })
|
|
23
|
+
},
|
|
24
|
+
"modelModifiers": {}
|
|
25
|
+
}),
|
|
26
|
+
emits: ["update:modelValue"],
|
|
27
|
+
setup(__props) {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
const model = vue.useModel(__props, "modelValue");
|
|
30
|
+
const localValue = vue.ref({
|
|
31
|
+
min: ((_a = model.value) == null ? void 0 : _a.min) || null,
|
|
32
|
+
max: ((_b = model.value) == null ? void 0 : _b.max) || null
|
|
33
|
+
});
|
|
34
|
+
vue.watch(model, (val) => {
|
|
35
|
+
if (val) {
|
|
36
|
+
localValue.value = {
|
|
37
|
+
min: val.min || null,
|
|
38
|
+
max: val.max || null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}, { deep: true });
|
|
42
|
+
const updateValue = () => {
|
|
43
|
+
model.value = { ...localValue.value };
|
|
44
|
+
};
|
|
45
|
+
const applyPreset = (preset) => {
|
|
46
|
+
localValue.value = {
|
|
47
|
+
min: preset.min || null,
|
|
48
|
+
max: preset.max || null
|
|
49
|
+
};
|
|
50
|
+
updateValue();
|
|
51
|
+
};
|
|
52
|
+
const isPresetActive = (preset) => {
|
|
53
|
+
return localValue.value.min === preset.min && localValue.value.max === preset.max;
|
|
54
|
+
};
|
|
55
|
+
return (_ctx, _cache) => {
|
|
56
|
+
var _a2;
|
|
57
|
+
return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
|
|
58
|
+
vue.createElementVNode("div", _hoisted_2, [
|
|
59
|
+
vue.createVNode(Field.default, {
|
|
60
|
+
type: "number",
|
|
61
|
+
field: localValue.value.min,
|
|
62
|
+
"onUpdate:field": _cache[0] || (_cache[0] = ($event) => localValue.value.min = $event),
|
|
63
|
+
placeholder: "Min",
|
|
64
|
+
class: "flex-1 bg-light pd-medium radius-small",
|
|
65
|
+
onBlur: updateValue
|
|
66
|
+
}, null, 8, ["field"]),
|
|
67
|
+
_cache[2] || (_cache[2] = vue.createElementVNode("span", { class: "t-small" }, "—", -1)),
|
|
68
|
+
vue.createVNode(Field.default, {
|
|
69
|
+
type: "number",
|
|
70
|
+
field: localValue.value.max,
|
|
71
|
+
"onUpdate:field": _cache[1] || (_cache[1] = ($event) => localValue.value.max = $event),
|
|
72
|
+
placeholder: "Max",
|
|
73
|
+
class: "flex-1 bg-light pd-medium radius-small",
|
|
74
|
+
onBlur: updateValue
|
|
75
|
+
}, null, 8, ["field"])
|
|
76
|
+
]),
|
|
77
|
+
((_a2 = __props.config) == null ? void 0 : _a2.presets) ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_3, [
|
|
78
|
+
(vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(__props.config.presets, (preset) => {
|
|
79
|
+
return vue.openBlock(), vue.createElementBlock("button", {
|
|
80
|
+
key: preset.label,
|
|
81
|
+
onClick: ($event) => applyPreset(preset),
|
|
82
|
+
class: vue.normalizeClass(["btn btn-small mr-thin mb-thin", isPresetActive(preset) ? "btn-primary" : "btn-secondary"])
|
|
83
|
+
}, vue.toDisplayString(preset.label), 11, _hoisted_4);
|
|
84
|
+
}), 128))
|
|
85
|
+
])) : vue.createCommentVNode("", true)
|
|
86
|
+
]);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
exports.default = _sfc_main;
|
|
91
|
+
//# sourceMappingURL=FilterPrice.vue.cjs.map
|
package/dist/martyrs/src/modules/globals/views/components/sections/filters/FilterPrice.vue.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterPrice.vue.cjs","sources":["../../../../../../../../../src/modules/globals/views/components/sections/filters/FilterPrice.vue"],"sourcesContent":["<!-- filters/FilterPrice.vue -->\n<template>\n <div class=\"filter-price\">\n <div class=\"flex gap-thin align-center\">\n <Field\n type=\"number\"\n v-model:field=\"localValue.min\"\n placeholder=\"Min\"\n class=\"flex-1 bg-light pd-medium radius-small\"\n @blur=\"updateValue\"\n />\n <span class=\"t-small\">—</span>\n <Field\n type=\"number\"\n v-model:field=\"localValue.max\"\n placeholder=\"Max\"\n class=\"flex-1 bg-light pd-medium radius-small\"\n @blur=\"updateValue\"\n />\n </div>\n \n <div v-if=\"config?.presets\" class=\"mt-thin\">\n <button\n v-for=\"preset in config.presets\"\n :key=\"preset.label\"\n @click=\"applyPreset(preset)\"\n class=\"btn btn-small mr-thin mb-thin\"\n :class=\"isPresetActive(preset) ? 'btn-primary' : 'btn-secondary'\"\n >\n {{ preset.label }}\n </button>\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref, watch } from 'vue'\nimport Field from '@martyrs/src/components/Field/Field.vue';\n\nconst props = defineProps({\n config: {\n type: Object,\n default: () => ({})\n }\n})\n\nconst model = defineModel({\n type: Object,\n default: () => ({ min: null, max: null })\n})\n\nconst localValue = ref({ \n min: model.value?.min || null, \n max: model.value?.max || null \n})\n\nwatch(model, (val) => {\n if (val) {\n localValue.value = { \n min: val.min || null, \n max: val.max || null \n }\n }\n}, { deep: true })\n\nconst updateValue = () => {\n model.value = { ...localValue.value }\n}\n\nconst applyPreset = (preset) => {\n localValue.value = { \n min: preset.min || null, \n max: preset.max || null \n }\n updateValue()\n}\n\nconst isPresetActive = (preset) => {\n return localValue.value.min === preset.min && localValue.value.max === preset.max\n}\n</script>"],"names":["_useModel","ref","watch"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,UAAM,QAAQA,IAAAA,SAGb,SAAA,YAAA;AAED,UAAM,aAAaC,IAAAA,IAAI;AAAA,MACrB,OAAK,WAAM,UAAN,mBAAa,QAAO;AAAA,MACzB,OAAK,WAAM,UAAN,mBAAa,QAAO;AAAA,IAC3B,CAAC;AAEDC,QAAAA,MAAM,OAAO,CAAC,QAAQ;AACpB,UAAI,KAAK;AACP,mBAAW,QAAQ;AAAA,UACjB,KAAK,IAAI,OAAO;AAAA,UAChB,KAAK,IAAI,OAAO;AAAA,QACtB;AAAA,MACA;AAAA,IACA,GAAG,EAAE,MAAM,KAAM,CAAA;AAEjB,UAAM,cAAc,MAAM;AACxB,YAAM,QAAQ,EAAE,GAAG,WAAW,MAAK;AAAA,IACrC;AAEA,UAAM,cAAc,CAAC,WAAW;AAC9B,iBAAW,QAAQ;AAAA,QACjB,KAAK,OAAO,OAAO;AAAA,QACnB,KAAK,OAAO,OAAO;AAAA,MACvB;AACE,kBAAW;AAAA,IACb;AAEA,UAAM,iBAAiB,CAAC,WAAW;AACjC,aAAO,WAAW,MAAM,QAAQ,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO;AAAA,IAChF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|