@dragonmastery/dragoncore-vue 0.0.21 → 0.0.23
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/{AppLink-CHMMrSFI.js → AppLink-FcNGKgvG.js} +1 -1
- package/dist/{AppLink-CHMMrSFI.js.map → AppLink-FcNGKgvG.js.map} +1 -1
- package/dist/Appearance-Ch4zfWZ3.js +3 -0
- package/dist/{Appearance-DxWTyx1M.js → Appearance-shr0Aql0.js} +1 -1
- package/dist/{Appearance-DxWTyx1M.js.map → Appearance-shr0Aql0.js.map} +1 -1
- package/dist/{ChangePasswordPage--3XwluwE.js → ChangePasswordPage-C633yQiU.js} +2 -2
- package/dist/{ChangePasswordPage--3XwluwE.js.map → ChangePasswordPage-C633yQiU.js.map} +1 -1
- package/dist/ChangePasswordPage-CYuCCosx.js +7 -0
- package/dist/ConfirmDialog-DjthOYU6.js +85 -0
- package/dist/ConfirmDialog-DjthOYU6.js.map +1 -0
- package/dist/ConsentRequired-BPjsZoPY.js +211 -0
- package/dist/ConsentRequired-BPjsZoPY.js.map +1 -0
- package/dist/CreateTeamForm-CeaC41VY.js +142 -0
- package/dist/CreateTeamForm-CeaC41VY.js.map +1 -0
- package/dist/CreateTeamForm-DfgCaUwX.js +12 -0
- package/dist/CreateTeamMemberForm-Bv9gNG4z.js +140 -0
- package/dist/CreateTeamMemberForm-Bv9gNG4z.js.map +1 -0
- package/dist/CreateTeamMemberForm-CnHfpob_.js +12 -0
- package/dist/CreateUserPage-C9uOeYDJ.js +7 -0
- package/dist/{CreateUserPage-DLwXeLAq.js → CreateUserPage-CqKcY7_X.js} +2 -2
- package/dist/{CreateUserPage-DLwXeLAq.js.map → CreateUserPage-CqKcY7_X.js.map} +1 -1
- package/dist/CreditBalanceDashboard-0HiJE_OS.js +13 -0
- package/dist/CreditBalanceDashboard-k_orNn4h.js +28 -0
- package/dist/CreditBalanceDashboard-k_orNn4h.js.map +1 -0
- package/dist/CreditManagement-BVBZQDI4.js +356 -0
- package/dist/CreditManagement-BVBZQDI4.js.map +1 -0
- package/dist/CreditManagement-DXdIN-0d.js +13 -0
- package/dist/CreditTransactionHistory-DSu-6aDi.js +229 -0
- package/dist/CreditTransactionHistory-DSu-6aDi.js.map +1 -0
- package/dist/CustomerCreateSupportTicketForm-BsjX8Pja.js +14 -0
- package/dist/CustomerCreateSupportTicketForm-kf8YIGjx.js +158 -0
- package/dist/CustomerCreateSupportTicketForm-kf8YIGjx.js.map +1 -0
- package/dist/{CustomerSupportTicketDetailPage-BdyaKG1v.js → CustomerSupportTicketDetailPage-C_-YoAaP.js} +12 -9
- package/dist/{CustomerSupportTicketDetailPage-BdyaKG1v.js.map → CustomerSupportTicketDetailPage-C_-YoAaP.js.map} +1 -1
- package/dist/CustomerSupportTicketList-DdACn3ug.js +63 -0
- package/dist/{CustomerSupportTicketParent-HIxwSVdu.js → CustomerSupportTicketParent-BpBuYCrP.js} +4 -4
- package/dist/{CustomerSupportTicketParent-HIxwSVdu.js.map → CustomerSupportTicketParent-BpBuYCrP.js.map} +1 -1
- package/dist/CustomerSupportTicketParent-Djy7pNqO.js +8 -0
- package/dist/CustomerSupportTicketSuccess-DsFzpJFU.js +12 -0
- package/dist/CustomerSupportTicketSuccess-cumNSGdx.js +54 -0
- package/dist/CustomerSupportTicketSuccess-cumNSGdx.js.map +1 -0
- package/dist/EditTeamForm-BE3iX2x3.js +12 -0
- package/dist/EditTeamForm-BxRN338L.js +163 -0
- package/dist/EditTeamForm-BxRN338L.js.map +1 -0
- package/dist/EditTeamMemberForm-D7D1Zddh.js +9 -0
- package/dist/{EditTeamMemberForm-CaS2GLjV.js → EditTeamMemberForm-DfgJr5Cy.js} +7 -72
- package/dist/EditTeamMemberForm-DfgJr5Cy.js.map +1 -0
- package/dist/EditUserPage-C0K7EGjM.js +8 -0
- package/dist/{EditUserPage-DURc5rmi.js → EditUserPage-CI_jtU8P.js} +4 -4
- package/dist/{EditUserPage-DURc5rmi.js.map → EditUserPage-CI_jtU8P.js.map} +1 -1
- package/dist/EnhancedRefreshTokenHandler-C6tZCcfX.js +189 -0
- package/dist/EnhancedRefreshTokenHandler-C6tZCcfX.js.map +1 -0
- package/dist/FieldsetSection-Cd4B8Ad7.js +27 -0
- package/dist/FieldsetSection-Cd4B8Ad7.js.map +1 -0
- package/dist/{ForgotPassword-OjIPi9s9.js → ForgotPassword-Ckb9Z-wb.js} +4 -4
- package/dist/{ForgotPassword-OjIPi9s9.js.map → ForgotPassword-Ckb9Z-wb.js.map} +1 -1
- package/dist/ForgotPassword-tJVSg7PB.js +8 -0
- package/dist/{TimelineSystemEvent-BHzFr46C.js → InlineAttachments-DAn_QknY.js} +60 -661
- package/dist/InlineAttachments-DAn_QknY.js.map +1 -0
- package/dist/{LoginForm-9UFnA-fO.js → LoginForm-CMN2T1fA.js} +5 -5
- package/dist/{LoginForm-9UFnA-fO.js.map → LoginForm-CMN2T1fA.js.map} +1 -1
- package/dist/LoginForm-QFJ8NHww.js +8 -0
- package/dist/{Logout-YgTgOFUH.js → Logout-CFLYHlLr.js} +5 -5
- package/dist/{Logout-YgTgOFUH.js.map → Logout-CFLYHlLr.js.map} +1 -1
- package/dist/Logout-CjDBff3W.js +8 -0
- package/dist/MfaSetup-BZcoxJx-.js +9 -0
- package/dist/{MfaSetup-RtFMY_dj.js → MfaSetup-XqoAwBXx.js} +5 -5
- package/dist/{MfaSetup-RtFMY_dj.js.map → MfaSetup-XqoAwBXx.js.map} +1 -1
- package/dist/{MfaVerify-Cvhe8bEM.js → MfaVerify-C-A75TFZ.js} +6 -6
- package/dist/{MfaVerify-Cvhe8bEM.js.map → MfaVerify-C-A75TFZ.js.map} +1 -1
- package/dist/MfaVerify-Dy2aV5Gk.js +9 -0
- package/dist/{RecordVersionViewer-BWZ78vvE.js → RecordVersionViewer-D2j10HdK.js} +1 -1
- package/dist/{RecordVersionViewer-BWZ78vvE.js.map → RecordVersionViewer-D2j10HdK.js.map} +1 -1
- package/dist/{ResetPassword-BE4mXK9q.js → ResetPassword-Cd-Yxp8E.js} +4 -4
- package/dist/{ResetPassword-BE4mXK9q.js.map → ResetPassword-Cd-Yxp8E.js.map} +1 -1
- package/dist/ResetPassword-D6to3G6a.js +8 -0
- package/dist/{SavedFiltersPage-DQt6uc8m.js → SavedFiltersPage-DM5DvAFa.js} +62 -34
- package/dist/{SavedFiltersPage-DQt6uc8m.js.map → SavedFiltersPage-DM5DvAFa.js.map} +1 -1
- package/dist/{Signup-9TjMMnU4.js → Signup-2pqvJiVt.js} +57 -57
- package/dist/Signup-2pqvJiVt.js.map +1 -0
- package/dist/Signup-XdImA1os.js +9 -0
- package/dist/{SignupConsentFlow-QUZGKjdB.js → SignupConsentFlow-X3kXuviv.js} +106 -70
- package/dist/SignupConsentFlow-X3kXuviv.js.map +1 -0
- package/dist/{SignupRequirementsPage-DfbYmpQD.js → SignupRequirementsPage-Cf-ElkEq.js} +9 -8
- package/dist/{SignupRequirementsPage-DfbYmpQD.js.map → SignupRequirementsPage-Cf-ElkEq.js.map} +1 -1
- package/dist/StaffCreateSupportTicketForm-BlUP2XXy.js +14 -0
- package/dist/StaffCreateSupportTicketForm-D2nn4rTU.js +255 -0
- package/dist/StaffCreateSupportTicketForm-D2nn4rTU.js.map +1 -0
- package/dist/{StaffSupportTicketDetailPage-DQdfh6H1.js → StaffSupportTicketDetailPage-MFtm06BE.js} +14 -11
- package/dist/{StaffSupportTicketDetailPage-DQdfh6H1.js.map → StaffSupportTicketDetailPage-MFtm06BE.js.map} +1 -1
- package/dist/StaffSupportTicketList-LfLx0pYP.js +63 -0
- package/dist/StaffSupportTicketParent-B7mEN1oD.js +8 -0
- package/dist/{StaffSupportTicketParent-CilR4RGM.js → StaffSupportTicketParent-BvPwgOqH.js} +4 -4
- package/dist/{StaffSupportTicketParent-CilR4RGM.js.map → StaffSupportTicketParent-BvPwgOqH.js.map} +1 -1
- package/dist/StaffSupportTicketSuccess-BMCOP3ko.js +12 -0
- package/dist/StaffSupportTicketSuccess-Ca2WrcRg.js +54 -0
- package/dist/StaffSupportTicketSuccess-Ca2WrcRg.js.map +1 -0
- package/dist/{SupportStaffPage-KKugAnFm.js → SupportStaffPage-B69-kuvg.js} +8 -7
- package/dist/{SupportStaffPage-KKugAnFm.js.map → SupportStaffPage-B69-kuvg.js.map} +1 -1
- package/dist/{SupportTicketDevLifecycleBadge-EMrQHfyG.js → SupportTicketDevLifecycleBadge-BoAjMb08.js} +1 -1
- package/dist/{SupportTicketDevLifecycleBadge-EMrQHfyG.js.map → SupportTicketDevLifecycleBadge-BoAjMb08.js.map} +1 -1
- package/dist/{SupportTicketMaintenancePage-smItdkrD.js → SupportTicketMaintenancePage-Bptja-xb.js} +5 -4
- package/dist/{SupportTicketMaintenancePage-smItdkrD.js.map → SupportTicketMaintenancePage-Bptja-xb.js.map} +1 -1
- package/dist/TeamAttachmentsTab-Dk3LxX3n.js +63 -0
- package/dist/TeamHistoryTab-CRONdHcL.js +6 -0
- package/dist/{TeamHistoryTab-D5biUPmq.js → TeamHistoryTab-DM8KBEG1.js} +7 -19
- package/dist/TeamHistoryTab-DM8KBEG1.js.map +1 -0
- package/dist/TeamList-DYm_vQ2z.js +8 -0
- package/dist/TeamList-qdwlMuJv.js +141 -0
- package/dist/TeamList-qdwlMuJv.js.map +1 -0
- package/dist/TeamMemberList-4LRLT_7Z.js +7 -0
- package/dist/TeamMemberList-DyI1U1t_.js +166 -0
- package/dist/TeamMemberList-DyI1U1t_.js.map +1 -0
- package/dist/TeamMemberParent-B63pRfI6.js +10 -0
- package/dist/TeamMemberParent-D9Fxu7GD.js +83 -0
- package/dist/TeamMemberParent-D9Fxu7GD.js.map +1 -0
- package/dist/TeamMembersTab-BGcdyEE8.js +3 -0
- package/dist/{TeamMembersTab-4gmnP9sD.js → TeamMembersTab-BigqpBDH.js} +1 -1
- package/dist/{TeamMembersTab-4gmnP9sD.js.map → TeamMembersTab-BigqpBDH.js.map} +1 -1
- package/dist/{TeamNotesTab-BzGZZ1h8.js → TeamNotesTab-BgxleidZ.js} +6 -5
- package/dist/{TeamNotesTab-BzGZZ1h8.js.map → TeamNotesTab-BgxleidZ.js.map} +1 -1
- package/dist/TeamNotesTab-o7glfjoY.js +8 -0
- package/dist/TeamParent-BwXqA3rj.js +83 -0
- package/dist/TeamParent-BwXqA3rj.js.map +1 -0
- package/dist/TeamParent-CFOmyKPz.js +11 -0
- package/dist/{TimelineNoteInput-0p-M4Qie.js → TimelineNoteInput-DXaodm43.js} +3 -2
- package/dist/{TimelineNoteInput-0p-M4Qie.js.map → TimelineNoteInput-DXaodm43.js.map} +1 -1
- package/dist/TimelineSystemEvent-zCMUx5Zz.js +525 -0
- package/dist/TimelineSystemEvent-zCMUx5Zz.js.map +1 -0
- package/dist/UserListPage-Bmwg0an5.js +5 -0
- package/dist/{UserListPage-DUE5gJTo.js → UserListPage-DtA8tLff.js} +4 -3
- package/dist/{UserListPage-DUE5gJTo.js.map → UserListPage-DtA8tLff.js.map} +1 -1
- package/dist/UserProfilePage-DRbCAr9H.js +8 -0
- package/dist/{UserProfilePage-C3b93Keh.js → UserProfilePage-g4-VEDXo.js} +4 -4
- package/dist/{UserProfilePage-C3b93Keh.js.map → UserProfilePage-g4-VEDXo.js.map} +1 -1
- package/dist/{VerifyEmail-DlOmWGG-.js → VerifyEmail-CM5ehFB8.js} +7 -7
- package/dist/{VerifyEmail-DlOmWGG-.js.map → VerifyEmail-CM5ehFB8.js.map} +1 -1
- package/dist/VerifyEmail-DMHczC9f.js +10 -0
- package/dist/ViewTeam-CXyABxE6.js +8 -0
- package/dist/ViewTeam-DSbKV60o.js +220 -0
- package/dist/ViewTeam-DSbKV60o.js.map +1 -0
- package/dist/ViewTeamMember-BB0nvPOe.js +167 -0
- package/dist/ViewTeamMember-BB0nvPOe.js.map +1 -0
- package/dist/ViewTeamMember-jrOnBaDh.js +7 -0
- package/dist/ZiniaContainer-CjVhCnGB.js +18 -0
- package/dist/ZiniaContainer-CjVhCnGB.js.map +1 -0
- package/dist/{convertToLocalDateTime-CFhtN6PI.js → convertToLocalDateTime-BF25N4xd.js} +1 -2
- package/dist/convertToLocalDateTime-BF25N4xd.js.map +1 -0
- package/dist/customerSupportTicketRoutes-C7OxGAGl.js +142 -0
- package/dist/customerSupportTicketRoutes-C7OxGAGl.js.map +1 -0
- package/dist/{displayIdFormatter-Dz900Awr.js → displayIdFormatter-B-_WQHOr.js} +1 -1
- package/dist/{displayIdFormatter-Dz900Awr.js.map → displayIdFormatter-B-_WQHOr.js.map} +1 -1
- package/dist/{extractRpcErrorMessage-Di8E8-Wh.js → extractRpcErrorMessage-diUBl6Ij.js} +1 -1
- package/dist/{extractRpcErrorMessage-Di8E8-Wh.js.map → extractRpcErrorMessage-diUBl6Ij.js.map} +1 -1
- package/dist/index.d.ts +793 -834
- package/dist/index.js +66 -38
- package/dist/{mfaSchema-BnRWf0ma.js → mfaSchema-Ukqzdyck.js} +1 -1
- package/dist/{mfaSchema-BnRWf0ma.js.map → mfaSchema-Ukqzdyck.js.map} +1 -1
- package/dist/saved_filter-CfzH0BzK.js +1210 -0
- package/dist/saved_filter-CfzH0BzK.js.map +1 -0
- package/dist/signupConsentStorage-DS9vCUuC.js +27 -0
- package/dist/signupConsentStorage-DS9vCUuC.js.map +1 -0
- package/dist/{src-CEBiyg_f.css → src-C6ZmNSSU.css} +1 -1
- package/dist/{src-CEBiyg_f.css.map → src-C6ZmNSSU.css.map} +1 -1
- package/dist/src-DVe_0RO9.js +4654 -0
- package/dist/src-DVe_0RO9.js.map +1 -0
- package/dist/staffSupportTicketRoutes-CWutoQWp.js +135 -0
- package/dist/staffSupportTicketRoutes-CWutoQWp.js.map +1 -0
- package/dist/teamMemberMetadata-CQnbVepq.js +49 -0
- package/dist/teamMemberMetadata-CQnbVepq.js.map +1 -0
- package/dist/teamMetadata-DlvwO5V0.js +53 -0
- package/dist/teamMetadata-DlvwO5V0.js.map +1 -0
- package/dist/teamRoutes-KFgnsdDP.js +192 -0
- package/dist/teamRoutes-KFgnsdDP.js.map +1 -0
- package/dist/team_memberRoutes-Cjpw_ql6.js +84 -0
- package/dist/team_memberRoutes-Cjpw_ql6.js.map +1 -0
- package/dist/{useBreadcrumbs-qB6ghsAf.js → useBreadcrumbs-DIqU5AAp.js} +1 -1
- package/dist/{useBreadcrumbs-qB6ghsAf.js.map → useBreadcrumbs-DIqU5AAp.js.map} +1 -1
- package/dist/{useEmailVerificationChannel-BNi926Ho.js → useEmailVerificationChannel-B51z65PN.js} +3 -3
- package/dist/{useEmailVerificationChannel-BNi926Ho.js.map → useEmailVerificationChannel-B51z65PN.js.map} +1 -1
- package/dist/{useMutation-BTsyHKyn.js → useMutation-BLNuJoYl.js} +6 -3
- package/dist/useMutation-BLNuJoYl.js.map +1 -0
- package/dist/{useQuery-BggIE52P.js → useQuery-BzUGEOj0.js} +4 -3
- package/dist/{useQuery-BggIE52P.js.map → useQuery-BzUGEOj0.js.map} +1 -1
- package/dist/{useQueryCache-Bjm-S8v5.js → useQueryCache-alzaRWEb.js} +2 -2
- package/dist/{useQueryCache-Bjm-S8v5.js.map → useQueryCache-alzaRWEb.js.map} +1 -1
- package/dist/{useReturnUrl-qFeazn-G.js → useReturnUrl-B5V3SJf5.js} +1 -1
- package/dist/{useReturnUrl-qFeazn-G.js.map → useReturnUrl-B5V3SJf5.js.map} +1 -1
- package/dist/{useRpcAuth-rmHf7bYx.js → useRpcAuth-CJtq1dqM.js} +25 -194
- package/dist/useRpcAuth-CJtq1dqM.js.map +1 -0
- package/dist/userAuthorized-C09FHWGL.js +185 -0
- package/dist/userAuthorized-C09FHWGL.js.map +1 -0
- package/package.json +3 -3
- package/dist/Appearance-D5pwxuf4.js +0 -3
- package/dist/ChangePasswordPage-CpDPmEml.js +0 -6
- package/dist/ConsentRequired-C4IRMA0c.js +0 -213
- package/dist/ConsentRequired-C4IRMA0c.js.map +0 -1
- package/dist/CreateTeamForm-B4cIuYAf.js +0 -35
- package/dist/CreateTeamMemberForm-Chrw1y00.js +0 -35
- package/dist/CreateUserPage-WruMs7WP.js +0 -6
- package/dist/CreditBalanceDashboard-CkcsrZ_e.js +0 -35
- package/dist/CreditManagement-Ddvu9dMw.js +0 -35
- package/dist/CustomerCreateSupportTicketForm-BKperKGS.js +0 -35
- package/dist/CustomerSupportTicketList-DcbrjDa9.js +0 -35
- package/dist/CustomerSupportTicketParent-BeNzUwuP.js +0 -7
- package/dist/CustomerSupportTicketSuccess-CC967u3y.js +0 -35
- package/dist/EditTeamForm-B5Tee5wL.js +0 -35
- package/dist/EditTeamMemberForm-CaS2GLjV.js.map +0 -1
- package/dist/EditTeamMemberForm-OtcS8QWt.js +0 -6
- package/dist/EditUserPage-T4DQlKhf.js +0 -7
- package/dist/ForgotPassword-CUifhmqP.js +0 -7
- package/dist/LoginForm-Bg7GoZEA.js +0 -7
- package/dist/Logout-Bs92csWH.js +0 -7
- package/dist/MfaSetup-BACX5XP-.js +0 -8
- package/dist/MfaVerify-ak4iSdQ2.js +0 -8
- package/dist/ResetPassword-pY1uhTdl.js +0 -7
- package/dist/Signup-9TjMMnU4.js.map +0 -1
- package/dist/Signup-Bq-G3D-s.js +0 -9
- package/dist/SignupConsentFlow-QUZGKjdB.js.map +0 -1
- package/dist/StaffCreateSupportTicketForm-D0ZuisDk.js +0 -35
- package/dist/StaffSupportTicketList-CiqC05XB.js +0 -35
- package/dist/StaffSupportTicketParent-DkV329NI.js +0 -7
- package/dist/StaffSupportTicketSuccess-CUYnimaI.js +0 -35
- package/dist/TeamAttachmentsTab-DUtCD1Yi.js +0 -35
- package/dist/TeamHistoryTab-BsUoH4VK.js +0 -4
- package/dist/TeamHistoryTab-D5biUPmq.js.map +0 -1
- package/dist/TeamList-BkPIqZ8V.js +0 -35
- package/dist/TeamMemberList-1mxUGCNa.js +0 -35
- package/dist/TeamMemberParent-DzeBIElY.js +0 -35
- package/dist/TeamMembersTab-CBB2Yl_I.js +0 -3
- package/dist/TeamNotesTab-ClHl2nXd.js +0 -7
- package/dist/TeamParent-DJa9UZTP.js +0 -35
- package/dist/TimelineSystemEvent-BHzFr46C.js.map +0 -1
- package/dist/UserListPage-BTLE4J0s.js +0 -4
- package/dist/UserProfilePage-CVTORtSx.js +0 -7
- package/dist/VerifyEmail-DCP4DWIw.js +0 -9
- package/dist/ViewTeam-DVfnLMhV.js +0 -35
- package/dist/ViewTeamMember-L4v3gCIn.js +0 -35
- package/dist/convertToLocalDateTime-CFhtN6PI.js.map +0 -1
- package/dist/src-QZJyMfGX.js +0 -8951
- package/dist/src-QZJyMfGX.js.map +0 -1
- package/dist/useMutation-BTsyHKyn.js.map +0 -1
- package/dist/useRpcAuth-rmHf7bYx.js.map +0 -1
- package/dist/useSignupPendingData-BWHwUHhL.js +0 -47
- package/dist/useSignupPendingData-BWHwUHhL.js.map +0 -1
|
@@ -0,0 +1,1210 @@
|
|
|
1
|
+
import { t as useMutation } from "./useMutation-BLNuJoYl.js";
|
|
2
|
+
import { t as useQuery } from "./useQuery-BzUGEOj0.js";
|
|
3
|
+
import { t as ConfirmDialog_default } from "./ConfirmDialog-DjthOYU6.js";
|
|
4
|
+
import { c as userAuthenticated } from "./userAuthorized-C09FHWGL.js";
|
|
5
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, nextTick, normalizeClass, onMounted, openBlock, ref, renderList, renderSlot, toDisplayString, unref, vModelText, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
|
|
6
|
+
import { MAX_PRESETS_PER_CONTEXT, OPERATORS } from "@dragonmastery/dragoncore-shared";
|
|
7
|
+
|
|
8
|
+
//#region src/components/BaseModal.vue
|
|
9
|
+
const _hoisted_1$4 = { class: "modal-box max-w-md w-full max-h-[90vh] flex flex-col p-0" };
|
|
10
|
+
const _hoisted_2$4 = { class: "flex justify-between items-center p-6 pb-4 border-b border-base-300 flex-shrink-0" };
|
|
11
|
+
const _hoisted_3$4 = { class: "font-bold text-lg" };
|
|
12
|
+
const _hoisted_4$4 = { class: "modal-content flex-1 overflow-y-auto p-6" };
|
|
13
|
+
const _hoisted_5$3 = {
|
|
14
|
+
method: "dialog",
|
|
15
|
+
class: "modal-backdrop"
|
|
16
|
+
};
|
|
17
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
18
|
+
__name: "BaseModal",
|
|
19
|
+
props: {
|
|
20
|
+
isOpen: { type: Boolean },
|
|
21
|
+
title: { default: "" }
|
|
22
|
+
},
|
|
23
|
+
emits: ["close"],
|
|
24
|
+
setup(__props, { emit: __emit }) {
|
|
25
|
+
const props = __props;
|
|
26
|
+
const emit = __emit;
|
|
27
|
+
const modal = ref();
|
|
28
|
+
const handleClose = () => {
|
|
29
|
+
emit("close");
|
|
30
|
+
};
|
|
31
|
+
watch(() => props.isOpen, (isOpen) => {
|
|
32
|
+
if (isOpen && modal.value) modal.value.showModal();
|
|
33
|
+
else if (!isOpen && modal.value) modal.value.close();
|
|
34
|
+
}, { immediate: true });
|
|
35
|
+
return (_ctx, _cache) => {
|
|
36
|
+
return openBlock(), createElementBlock("dialog", {
|
|
37
|
+
ref_key: "modal",
|
|
38
|
+
ref: modal,
|
|
39
|
+
class: "modal"
|
|
40
|
+
}, [createElementVNode("div", _hoisted_1$4, [
|
|
41
|
+
createCommentVNode(" Header with title and close button - fixed, not scrollable "),
|
|
42
|
+
createElementVNode("div", _hoisted_2$4, [createElementVNode("h3", _hoisted_3$4, [renderSlot(_ctx.$slots, "title", {}, () => [createTextVNode(toDisplayString(__props.title), 1)])]), createElementVNode("button", {
|
|
43
|
+
type: "button",
|
|
44
|
+
class: "btn btn-sm btn-circle btn-ghost",
|
|
45
|
+
onClick: withModifiers(handleClose, ["prevent"]),
|
|
46
|
+
"aria-label": "Close modal"
|
|
47
|
+
}, [..._cache[0] || (_cache[0] = [createElementVNode("svg", {
|
|
48
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
49
|
+
class: "h-6 w-6",
|
|
50
|
+
fill: "none",
|
|
51
|
+
viewBox: "0 0 24 24",
|
|
52
|
+
stroke: "currentColor"
|
|
53
|
+
}, [createElementVNode("path", {
|
|
54
|
+
"stroke-linecap": "round",
|
|
55
|
+
"stroke-linejoin": "round",
|
|
56
|
+
"stroke-width": "2",
|
|
57
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
58
|
+
})], -1)])])]),
|
|
59
|
+
createCommentVNode(" Content slot - scrollable area "),
|
|
60
|
+
createElementVNode("div", _hoisted_4$4, [renderSlot(_ctx.$slots, "default")])
|
|
61
|
+
]), createElementVNode("form", _hoisted_5$3, [createElementVNode("button", {
|
|
62
|
+
type: "button",
|
|
63
|
+
onClick: withModifiers(handleClose, ["prevent"])
|
|
64
|
+
}, "close")])], 512);
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
var BaseModal_default = _sfc_main$4;
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/constants/time.ts
|
|
72
|
+
/**
|
|
73
|
+
* Time duration constants in milliseconds.
|
|
74
|
+
* Use for staleTime, cache TTL, etc.
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* staleTime: 30 * MS.ONE_SECOND
|
|
78
|
+
* staleTime: 5 * MS.ONE_MINUTE
|
|
79
|
+
* staleTime: 24 * MS.ONE_HOUR
|
|
80
|
+
*/
|
|
81
|
+
const MS = {
|
|
82
|
+
ONE_SECOND: 1e3,
|
|
83
|
+
ONE_MINUTE: 60 * 1e3,
|
|
84
|
+
ONE_HOUR: 3600 * 1e3
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
//#region src/slices/saved_filter/usePinnedPresets.ts
|
|
89
|
+
const CACHE_KEY = "pinned-presets";
|
|
90
|
+
const MAX_PINNED = 5;
|
|
91
|
+
function usePinnedPresets() {
|
|
92
|
+
const { data: pinnedData, refetch } = useQuery((api) => api.savedFilters.listPinnedPresets(), {
|
|
93
|
+
cacheKey: CACHE_KEY,
|
|
94
|
+
staleTime: 24 * MS.ONE_HOUR
|
|
95
|
+
});
|
|
96
|
+
const { mutate: addPin } = useMutation((api, id) => api.savedFilters.addPinnedPreset(id), { invalidate: CACHE_KEY });
|
|
97
|
+
const { mutate: removePin } = useMutation((api, id) => api.savedFilters.removePinnedPreset(id), { invalidate: CACHE_KEY });
|
|
98
|
+
const pinned = computed(() => pinnedData.value ?? []);
|
|
99
|
+
const pinnedIds = computed(() => new Set(pinned.value.map((p) => p.id)));
|
|
100
|
+
const canPinMore = computed(() => pinned.value.length < MAX_PINNED);
|
|
101
|
+
function isPinned(presetId) {
|
|
102
|
+
return pinnedIds.value.has(presetId);
|
|
103
|
+
}
|
|
104
|
+
async function pinPreset(preset) {
|
|
105
|
+
if (pinned.value.length >= MAX_PINNED) return false;
|
|
106
|
+
if (pinnedIds.value.has(preset.id)) return true;
|
|
107
|
+
try {
|
|
108
|
+
await addPin(preset.id);
|
|
109
|
+
await refetch();
|
|
110
|
+
return true;
|
|
111
|
+
} catch {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
async function unpinPreset(presetId) {
|
|
116
|
+
try {
|
|
117
|
+
await removePin(presetId);
|
|
118
|
+
await refetch();
|
|
119
|
+
} catch {}
|
|
120
|
+
}
|
|
121
|
+
async function togglePin(preset) {
|
|
122
|
+
if (isPinned(preset.id)) {
|
|
123
|
+
await unpinPreset(preset.id);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
return pinPreset(preset);
|
|
127
|
+
}
|
|
128
|
+
function getPresetLink(preset) {
|
|
129
|
+
return {
|
|
130
|
+
path: preset.route_path,
|
|
131
|
+
query: preset.filters ?? {}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function updatePinnedPreset(presetId, updates) {}
|
|
135
|
+
return {
|
|
136
|
+
pinned,
|
|
137
|
+
pinnedIds,
|
|
138
|
+
canPinMore,
|
|
139
|
+
isPinned,
|
|
140
|
+
pinPreset,
|
|
141
|
+
unpinPreset,
|
|
142
|
+
togglePin,
|
|
143
|
+
getPresetLink,
|
|
144
|
+
updatePinnedPreset,
|
|
145
|
+
refetchPinned: refetch,
|
|
146
|
+
maxPinned: MAX_PINNED
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const PINNED_PRESETS_KEY = Symbol("pinnedPresets");
|
|
150
|
+
/** Use pinned presets from the layout provider. Call this in child components (Sidebar, AppHome, etc.). */
|
|
151
|
+
function useInjectedPinnedPresets() {
|
|
152
|
+
const injected = inject(PINNED_PRESETS_KEY);
|
|
153
|
+
if (!injected) throw new Error("useInjectedPinnedPresets must be used within a component tree that provides pinned presets (e.g. InAppLayout).");
|
|
154
|
+
return injected;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
//#endregion
|
|
158
|
+
//#region src/utils/filterUrlParser.ts
|
|
159
|
+
/**
|
|
160
|
+
* Filter URL Parser - Query string serialization/deserialization
|
|
161
|
+
* Uses compact DrizzleORM-style format: flt[field]=value or flt[field][op]=value
|
|
162
|
+
*/
|
|
163
|
+
/**
|
|
164
|
+
* Default operators for each field type when not specified in URL
|
|
165
|
+
*/
|
|
166
|
+
const DEFAULT_OPERATORS = {
|
|
167
|
+
string: OPERATORS.CONTAINS,
|
|
168
|
+
number: OPERATORS.EQUALS,
|
|
169
|
+
date: OPERATORS.EQUALS,
|
|
170
|
+
boolean: OPERATORS.EQUALS,
|
|
171
|
+
enum: OPERATORS.EQUALS
|
|
172
|
+
};
|
|
173
|
+
/**
|
|
174
|
+
* Numeric types that should be converted to numbers
|
|
175
|
+
*/
|
|
176
|
+
const NUMERIC_TYPES = [
|
|
177
|
+
"number",
|
|
178
|
+
"money",
|
|
179
|
+
"percentage"
|
|
180
|
+
];
|
|
181
|
+
/**
|
|
182
|
+
* Check if operator requires array values
|
|
183
|
+
*/
|
|
184
|
+
function requiresArrayValues(operator) {
|
|
185
|
+
return operator === OPERATORS.IS_ONE_OF || operator === OPERATORS.IS_NOT_ONE_OF || operator === OPERATORS.BETWEEN;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Check if operator is a null check (requires no value)
|
|
189
|
+
*/
|
|
190
|
+
function isNullCheckOperator(operator) {
|
|
191
|
+
return operator === OPERATORS.IS_EMPTY || operator === OPERATORS.IS_NOT_EMPTY;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Deserialize filter configuration from URL query parameters object
|
|
195
|
+
* Parses compact DrizzleORM-style format: flt[field]=value or flt[field][op]=value
|
|
196
|
+
*
|
|
197
|
+
* @param params - URL query parameters object (from Vue Router route.query)
|
|
198
|
+
* @param registry - Field registry metadata for type inference
|
|
199
|
+
* @returns Filter configuration object
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* // URL: ?flt[department][eq]=Engineering&flt[id]=4&flt[role][in]=["admin","user"]
|
|
203
|
+
* const filters = deserializeFiltersFromQueryParams(route.query, fieldRegistry);
|
|
204
|
+
* // Result: {
|
|
205
|
+
* // department: { operator: 'eq', value: 'Engineering' },
|
|
206
|
+
* // id: { operator: 'eq', value: 4 },
|
|
207
|
+
* // role: { operator: 'in', values: ['admin', 'user'] }
|
|
208
|
+
* // }
|
|
209
|
+
*/
|
|
210
|
+
function deserializeFiltersFromQueryParams(params, registry) {
|
|
211
|
+
const config = {};
|
|
212
|
+
const fieldMap = /* @__PURE__ */ new Map();
|
|
213
|
+
for (const [key, value] of Object.entries(params)) {
|
|
214
|
+
const matchDefault = key.match(/^flt\[([^\]]+)\]$/);
|
|
215
|
+
const matchWithOp = key.match(/^flt\[([^\]]+)\]\[([^\]]+)\]$/);
|
|
216
|
+
if (!matchDefault && !matchWithOp) continue;
|
|
217
|
+
const fieldName = matchDefault ? matchDefault[1] : matchWithOp ? matchWithOp[1] : null;
|
|
218
|
+
const operatorShorthand = matchWithOp ? matchWithOp[2] : null;
|
|
219
|
+
const stringValue = Array.isArray(value) ? value[0] : value;
|
|
220
|
+
if (!fieldName) continue;
|
|
221
|
+
const fieldMeta = registry[fieldName];
|
|
222
|
+
if (!fieldMeta) continue;
|
|
223
|
+
const fieldType = fieldMeta.type;
|
|
224
|
+
const defaultOp = DEFAULT_OPERATORS[fieldType] || OPERATORS.EQUALS;
|
|
225
|
+
let operator;
|
|
226
|
+
if (operatorShorthand) operator = operatorShorthand;
|
|
227
|
+
else operator = defaultOp;
|
|
228
|
+
if (!fieldMap.has(fieldName)) fieldMap.set(fieldName, { operator });
|
|
229
|
+
const filter = fieldMap.get(fieldName);
|
|
230
|
+
filter.operator = operator;
|
|
231
|
+
if (isNullCheckOperator(operator)) {} else if (requiresArrayValues(operator)) {
|
|
232
|
+
if (!stringValue || stringValue.trim() === "") {
|
|
233
|
+
fieldMap.delete(fieldName);
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
try {
|
|
237
|
+
const parsed = JSON.parse(stringValue);
|
|
238
|
+
if (Array.isArray(parsed) && parsed.length > 0) if (NUMERIC_TYPES.includes(fieldType)) filter.values = parsed.map((v) => Number(v));
|
|
239
|
+
else filter.values = parsed;
|
|
240
|
+
else {
|
|
241
|
+
fieldMap.delete(fieldName);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
} catch (e) {
|
|
245
|
+
const values = stringValue.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
|
|
246
|
+
if (values.length === 0) {
|
|
247
|
+
fieldMap.delete(fieldName);
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (operator === OPERATORS.BETWEEN && values.length === 2) if (NUMERIC_TYPES.includes(fieldType)) filter.values = [Number(values[0]), Number(values[1])];
|
|
251
|
+
else if (fieldType === "date") filter.values = [values[0], values[1]];
|
|
252
|
+
else filter.values = values;
|
|
253
|
+
else if (operator === OPERATORS.BETWEEN) {
|
|
254
|
+
fieldMap.delete(fieldName);
|
|
255
|
+
continue;
|
|
256
|
+
} else if (NUMERIC_TYPES.includes(fieldType)) filter.values = values.map((v) => Number(v));
|
|
257
|
+
else filter.values = values;
|
|
258
|
+
}
|
|
259
|
+
} else if ((operator === OPERATORS.IS_ONE_OF || operator === OPERATORS.IS_NOT_ONE_OF) && stringValue) if (NUMERIC_TYPES.includes(fieldType)) filter.values = [Number(stringValue)];
|
|
260
|
+
else filter.values = [stringValue];
|
|
261
|
+
else if (stringValue) {
|
|
262
|
+
if (NUMERIC_TYPES.includes(fieldType)) filter.value = Number(stringValue);
|
|
263
|
+
else if (fieldType === "boolean") filter.value = stringValue === "true" || stringValue === "1";
|
|
264
|
+
else filter.value = stringValue;
|
|
265
|
+
if (fieldType === "string" && operator === OPERATORS.CONTAINS) filter.caseSensitive = false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
for (const [fieldName, filter] of fieldMap.entries()) if (filter.operator) config[fieldName] = filter;
|
|
269
|
+
return config;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Serialize filter configuration to URL query parameters object
|
|
273
|
+
* Uses compact DrizzleORM-style format: flt[field][op]=value
|
|
274
|
+
*
|
|
275
|
+
* @param config - Filter configuration object
|
|
276
|
+
* @param registry - Field registry metadata for type inference
|
|
277
|
+
* @returns URL query parameters object (can be used with Vue Router)
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* const filters = {
|
|
281
|
+
* department: { operator: 'eq', value: 'Engineering' },
|
|
282
|
+
* role: { operator: 'in', values: ['admin', 'user'] }
|
|
283
|
+
* };
|
|
284
|
+
* const params = serializeFiltersToQueryParams(filters, fieldRegistry);
|
|
285
|
+
* // Result: {
|
|
286
|
+
* // 'flt[department][eq]': 'Engineering',
|
|
287
|
+
* // 'flt[role][in]': '["admin","user"]'
|
|
288
|
+
* // }
|
|
289
|
+
*/
|
|
290
|
+
function serializeFiltersToQueryParams(config, registry) {
|
|
291
|
+
const params = {};
|
|
292
|
+
for (const [fieldName, filter] of Object.entries(config)) {
|
|
293
|
+
if (!registry[fieldName]) continue;
|
|
294
|
+
const operator = filter.operator;
|
|
295
|
+
if (isNullCheckOperator(operator)) params[`flt[${fieldName}][${operator}]`] = "";
|
|
296
|
+
else if (requiresArrayValues(operator)) {
|
|
297
|
+
if (filter.values && Array.isArray(filter.values)) params[`flt[${fieldName}][${operator}]`] = JSON.stringify(filter.values);
|
|
298
|
+
} else params[`flt[${fieldName}][${operator}]`] = String(filter.value);
|
|
299
|
+
}
|
|
300
|
+
return params;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Extract filter query params from route query.
|
|
304
|
+
* Handles Vue Router's LocationQuery type which can have null values.
|
|
305
|
+
* Only extracts flt[...] params (actual filters).
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* // URL: ?flt[type][in]=["sales","escalation"]&flt[phase][ne]=Post+Sale
|
|
309
|
+
* // Returns: { 'flt[type][in]': '["sales","escalation"]', 'flt[phase][ne]': 'Post+Sale' }
|
|
310
|
+
*/
|
|
311
|
+
function extractFiltersFromQuery(query) {
|
|
312
|
+
const filters = {};
|
|
313
|
+
Object.keys(query).forEach((key) => {
|
|
314
|
+
if (key.startsWith("flt[")) {
|
|
315
|
+
const value = query[key];
|
|
316
|
+
if (value !== null && value !== void 0) if (Array.isArray(value)) {
|
|
317
|
+
const filtered = value.filter((v) => v !== null && v !== void 0);
|
|
318
|
+
if (filtered.length > 0) filters[key] = filtered;
|
|
319
|
+
} else filters[key] = String(value);
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
return filters;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Build a new query object with filter params replaced (not merged).
|
|
326
|
+
* Strips all flt[...] params from the current query, then adds the new filters.
|
|
327
|
+
* Preserves non-filter params (sort, pagination, etc).
|
|
328
|
+
*/
|
|
329
|
+
function buildQueryWithFilters(currentQuery, filters) {
|
|
330
|
+
const base = {};
|
|
331
|
+
for (const [key, value] of Object.entries(currentQuery)) if (!key.startsWith("flt[") && value !== null && value !== void 0) base[key] = Array.isArray(value) ? value.filter((v) => v != null) : String(value);
|
|
332
|
+
return {
|
|
333
|
+
...base,
|
|
334
|
+
...filters
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region src/slices/saved_filter/lastUsedPresetGuard.ts
|
|
340
|
+
/**
|
|
341
|
+
* Router guard helper: redirect to last-used preset filters when navigating with no URL filters.
|
|
342
|
+
* Uses localStorage (no API call) - filters are stored when user applies a preset.
|
|
343
|
+
* Prevents double fetch by applying preset before the list component mounts.
|
|
344
|
+
*/
|
|
345
|
+
const LAST_USED_PREFIX$1 = "lastUsedPreset:";
|
|
346
|
+
const LAST_USED_FILTERS_PREFIX = "lastUsedPresetFilters:";
|
|
347
|
+
function getLastUsedKey$1(context) {
|
|
348
|
+
return `${LAST_USED_PREFIX$1}${context}`;
|
|
349
|
+
}
|
|
350
|
+
function getLastUsedFiltersKey(context) {
|
|
351
|
+
return `${LAST_USED_FILTERS_PREFIX}${context}`;
|
|
352
|
+
}
|
|
353
|
+
function getLastUsedPresetFilters(context) {
|
|
354
|
+
try {
|
|
355
|
+
const stored = localStorage.getItem(getLastUsedFiltersKey(context));
|
|
356
|
+
if (!stored) return null;
|
|
357
|
+
const parsed = JSON.parse(stored);
|
|
358
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
359
|
+
} catch {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
function setLastUsedPresetFilters(context, filters) {
|
|
364
|
+
try {
|
|
365
|
+
if (filters && Object.keys(filters).length > 0) localStorage.setItem(getLastUsedFiltersKey(context), JSON.stringify(filters));
|
|
366
|
+
else localStorage.removeItem(getLastUsedFiltersKey(context));
|
|
367
|
+
} catch {}
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* If navigating with no filters and we have a last-used preset, returns the query to redirect to.
|
|
371
|
+
* Otherwise returns null (no redirect needed).
|
|
372
|
+
*/
|
|
373
|
+
function getLastUsedPresetRedirect(context, currentQuery) {
|
|
374
|
+
const filters = extractFiltersFromQuery(currentQuery);
|
|
375
|
+
if (Object.keys(filters).length > 0) return null;
|
|
376
|
+
if (!localStorage.getItem(getLastUsedKey$1(context))) return null;
|
|
377
|
+
const lastUsedFilters = getLastUsedPresetFilters(context);
|
|
378
|
+
if (!lastUsedFilters || Object.keys(lastUsedFilters).length === 0) return null;
|
|
379
|
+
return buildQueryWithFilters(currentQuery, lastUsedFilters);
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Creates a Vue Router beforeEnter guard that redirects to last-used preset when navigating with no filters.
|
|
383
|
+
* Use on list routes that have SavedFilterPresets.
|
|
384
|
+
*/
|
|
385
|
+
function createLastUsedPresetGuard(context, routeName) {
|
|
386
|
+
return (to) => {
|
|
387
|
+
if (to.name !== routeName) return void 0;
|
|
388
|
+
const redirectQuery = getLastUsedPresetRedirect(context, to.query);
|
|
389
|
+
if (!redirectQuery) return void 0;
|
|
390
|
+
return {
|
|
391
|
+
name: routeName,
|
|
392
|
+
query: redirectQuery
|
|
393
|
+
};
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
//#endregion
|
|
398
|
+
//#region src/slices/saved_filter/useSavedFilters.ts
|
|
399
|
+
const LAST_USED_PREFIX = "lastUsedPreset:";
|
|
400
|
+
function getLastUsedKey(context) {
|
|
401
|
+
return `${LAST_USED_PREFIX}${context}`;
|
|
402
|
+
}
|
|
403
|
+
function getLastUsedPresetId(context) {
|
|
404
|
+
try {
|
|
405
|
+
return localStorage.getItem(getLastUsedKey(context));
|
|
406
|
+
} catch {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function setLastUsedPresetId(context, presetId) {
|
|
411
|
+
try {
|
|
412
|
+
if (presetId) localStorage.setItem(getLastUsedKey(context), presetId);
|
|
413
|
+
else localStorage.removeItem(getLastUsedKey(context));
|
|
414
|
+
} catch {}
|
|
415
|
+
}
|
|
416
|
+
function useSavedFilters(config) {
|
|
417
|
+
const { context, routePath, getFiltersFromTable, applyFiltersToTable, onClearFilters } = config;
|
|
418
|
+
const cacheKey = `saved-filters:${context}`;
|
|
419
|
+
const hasAppliedLastUsed = ref(false);
|
|
420
|
+
const lastUsedPresetIdRef = ref(getLastUsedPresetId(context));
|
|
421
|
+
const { data: presets, loading: presetsLoading, refetch: refetchPresets } = useQuery((api) => api.savedFilters.listSavedFilters(context), {
|
|
422
|
+
cacheKey,
|
|
423
|
+
staleTime: 24 * MS.ONE_HOUR
|
|
424
|
+
});
|
|
425
|
+
const { mutate: createPreset, loading: creating } = useMutation((api, input) => api.savedFilters.createSavedFilter(input), { invalidate: /^saved-filters:/ });
|
|
426
|
+
const { mutate: updatePreset, loading: updating } = useMutation((api, input) => api.savedFilters.updateSavedFilter(input), { invalidate: /^saved-filters:|^pinned-presets/ });
|
|
427
|
+
const { mutate: deletePreset, loading: deleting } = useMutation((api, id) => api.savedFilters.deleteSavedFilter(id), { invalidate: /^saved-filters:/ });
|
|
428
|
+
function applyPreset(preset) {
|
|
429
|
+
applyFiltersToTable(preset.filters);
|
|
430
|
+
setLastUsedPresetId(context, preset.id);
|
|
431
|
+
setLastUsedPresetFilters(context, preset.filters);
|
|
432
|
+
lastUsedPresetIdRef.value = preset.id;
|
|
433
|
+
}
|
|
434
|
+
function clearPreset() {
|
|
435
|
+
applyFiltersToTable({});
|
|
436
|
+
setLastUsedPresetId(context, null);
|
|
437
|
+
setLastUsedPresetFilters(context, null);
|
|
438
|
+
lastUsedPresetIdRef.value = null;
|
|
439
|
+
}
|
|
440
|
+
function clearLastUsed() {
|
|
441
|
+
setLastUsedPresetId(context, null);
|
|
442
|
+
setLastUsedPresetFilters(context, null);
|
|
443
|
+
lastUsedPresetIdRef.value = null;
|
|
444
|
+
onClearFilters?.();
|
|
445
|
+
}
|
|
446
|
+
async function saveCurrentFilters(name) {
|
|
447
|
+
const filters = getFiltersFromTable();
|
|
448
|
+
if (Object.keys(filters).length === 0) return null;
|
|
449
|
+
try {
|
|
450
|
+
const result = await createPreset({
|
|
451
|
+
name,
|
|
452
|
+
context,
|
|
453
|
+
route_path: routePath,
|
|
454
|
+
filters
|
|
455
|
+
});
|
|
456
|
+
if (result) {
|
|
457
|
+
await refetchPresets();
|
|
458
|
+
setLastUsedPresetId(context, result.id);
|
|
459
|
+
setLastUsedPresetFilters(context, result.filters);
|
|
460
|
+
lastUsedPresetIdRef.value = result.id;
|
|
461
|
+
}
|
|
462
|
+
return result ?? null;
|
|
463
|
+
} catch {
|
|
464
|
+
return null;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
async function updatePresetFilters(presetId, name) {
|
|
468
|
+
const filters = getFiltersFromTable();
|
|
469
|
+
try {
|
|
470
|
+
return await updatePreset({
|
|
471
|
+
id: presetId,
|
|
472
|
+
...name !== void 0 && { name },
|
|
473
|
+
filters
|
|
474
|
+
}) ?? null;
|
|
475
|
+
} catch {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
async function renamePreset(presetId, name) {
|
|
480
|
+
try {
|
|
481
|
+
const result = await updatePreset({
|
|
482
|
+
id: presetId,
|
|
483
|
+
name
|
|
484
|
+
});
|
|
485
|
+
if (result) await refetchPresets();
|
|
486
|
+
return result ?? null;
|
|
487
|
+
} catch {
|
|
488
|
+
return null;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
async function removePreset(presetId) {
|
|
492
|
+
try {
|
|
493
|
+
await deletePreset(presetId);
|
|
494
|
+
await refetchPresets();
|
|
495
|
+
return true;
|
|
496
|
+
} catch {
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
onMounted(() => {
|
|
501
|
+
const filters = getFiltersFromTable();
|
|
502
|
+
if (Object.keys(filters).length > 0) {
|
|
503
|
+
hasAppliedLastUsed.value = true;
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
const lastUsedId = getLastUsedPresetId(context);
|
|
507
|
+
if (!lastUsedId) {
|
|
508
|
+
hasAppliedLastUsed.value = true;
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
511
|
+
const unwatch = watch(() => presets.value, (list) => {
|
|
512
|
+
if (!list || hasAppliedLastUsed.value) return;
|
|
513
|
+
const preset = list.find((p) => p.id === lastUsedId);
|
|
514
|
+
if (preset) applyPreset(preset);
|
|
515
|
+
hasAppliedLastUsed.value = true;
|
|
516
|
+
unwatch();
|
|
517
|
+
}, { immediate: true });
|
|
518
|
+
});
|
|
519
|
+
const activePreset = computed(() => {
|
|
520
|
+
const id = lastUsedPresetIdRef.value;
|
|
521
|
+
if (!id) return null;
|
|
522
|
+
return (presets.value ?? []).find((p) => p.id === id) ?? null;
|
|
523
|
+
});
|
|
524
|
+
return {
|
|
525
|
+
presets: computed(() => presets.value ?? []),
|
|
526
|
+
presetsLoading,
|
|
527
|
+
creating,
|
|
528
|
+
updating,
|
|
529
|
+
deleting,
|
|
530
|
+
applyPreset,
|
|
531
|
+
clearPreset,
|
|
532
|
+
clearLastUsed,
|
|
533
|
+
activePreset,
|
|
534
|
+
saveCurrentFilters,
|
|
535
|
+
updatePresetFilters,
|
|
536
|
+
renamePreset,
|
|
537
|
+
removePreset
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
//#endregion
|
|
542
|
+
//#region src/slices/saved_filter/savedFilterRoutes.ts
|
|
543
|
+
const savedFilterRoutes = [{
|
|
544
|
+
path: "/saved-filters",
|
|
545
|
+
name: "SavedFilters",
|
|
546
|
+
component: () => import("./SavedFiltersPage-DM5DvAFa.js"),
|
|
547
|
+
beforeEnter: [userAuthenticated],
|
|
548
|
+
meta: {
|
|
549
|
+
title: "Saved Filters",
|
|
550
|
+
description: "Manage your saved filter presets and favorites",
|
|
551
|
+
side_bar: {
|
|
552
|
+
section: "Saved Filters",
|
|
553
|
+
visible_to: [
|
|
554
|
+
"consumer",
|
|
555
|
+
"lead",
|
|
556
|
+
"staff",
|
|
557
|
+
"super_admin"
|
|
558
|
+
]
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}];
|
|
562
|
+
|
|
563
|
+
//#endregion
|
|
564
|
+
//#region src/slices/saved_filter/SaveFilterModal.vue
|
|
565
|
+
const _hoisted_1$3 = { class: "form-control" };
|
|
566
|
+
const _hoisted_2$3 = {
|
|
567
|
+
key: 0,
|
|
568
|
+
class: "label"
|
|
569
|
+
};
|
|
570
|
+
const _hoisted_3$3 = { class: "label-text-alt text-error" };
|
|
571
|
+
const _hoisted_4$3 = { class: "flex justify-end gap-2" };
|
|
572
|
+
const _hoisted_5$2 = ["disabled"];
|
|
573
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
574
|
+
__name: "SaveFilterModal",
|
|
575
|
+
props: {
|
|
576
|
+
isOpen: { type: Boolean },
|
|
577
|
+
saving: { type: Boolean }
|
|
578
|
+
},
|
|
579
|
+
emits: ["close", "save"],
|
|
580
|
+
setup(__props, { emit: __emit }) {
|
|
581
|
+
const props = __props;
|
|
582
|
+
const emit = __emit;
|
|
583
|
+
const name = ref("");
|
|
584
|
+
const error = ref("");
|
|
585
|
+
function close() {
|
|
586
|
+
emit("close");
|
|
587
|
+
}
|
|
588
|
+
function handleSubmit() {
|
|
589
|
+
const trimmed = name.value.trim();
|
|
590
|
+
if (!trimmed) {
|
|
591
|
+
error.value = "Name is required";
|
|
592
|
+
return;
|
|
593
|
+
}
|
|
594
|
+
if (trimmed.length > 100) {
|
|
595
|
+
error.value = "Name must be 100 characters or less";
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
error.value = "";
|
|
599
|
+
emit("save", trimmed);
|
|
600
|
+
}
|
|
601
|
+
watch(() => props.isOpen, (open) => {
|
|
602
|
+
if (open) {
|
|
603
|
+
name.value = "";
|
|
604
|
+
error.value = "";
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
return (_ctx, _cache) => {
|
|
608
|
+
return openBlock(), createBlock(BaseModal_default, {
|
|
609
|
+
"is-open": __props.isOpen,
|
|
610
|
+
title: "Save Filter Preset",
|
|
611
|
+
onClose: close
|
|
612
|
+
}, {
|
|
613
|
+
default: withCtx(() => [createElementVNode("form", {
|
|
614
|
+
onSubmit: withModifiers(handleSubmit, ["prevent"]),
|
|
615
|
+
class: "space-y-4"
|
|
616
|
+
}, [createElementVNode("div", _hoisted_1$3, [
|
|
617
|
+
_cache[1] || (_cache[1] = createElementVNode("label", { class: "label" }, [createElementVNode("span", { class: "label-text" }, "Preset name")], -1)),
|
|
618
|
+
withDirectives(createElementVNode("input", {
|
|
619
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => name.value = $event),
|
|
620
|
+
type: "text",
|
|
621
|
+
placeholder: "e.g. My Sales Escalations",
|
|
622
|
+
class: "input input-bordered w-full",
|
|
623
|
+
maxlength: "100"
|
|
624
|
+
}, null, 512), [[vModelText, name.value]]),
|
|
625
|
+
error.value ? (openBlock(), createElementBlock("label", _hoisted_2$3, [createElementVNode("span", _hoisted_3$3, toDisplayString(error.value), 1)])) : createCommentVNode("v-if", true)
|
|
626
|
+
]), createElementVNode("div", _hoisted_4$3, [createElementVNode("button", {
|
|
627
|
+
type: "button",
|
|
628
|
+
class: "btn btn-ghost",
|
|
629
|
+
onClick: close
|
|
630
|
+
}, " Cancel "), createElementVNode("button", {
|
|
631
|
+
type: "submit",
|
|
632
|
+
class: "btn btn-primary",
|
|
633
|
+
disabled: __props.saving || !name.value.trim()
|
|
634
|
+
}, toDisplayString(__props.saving ? "Saving..." : "Save"), 9, _hoisted_5$2)])], 32)]),
|
|
635
|
+
_: 1
|
|
636
|
+
}, 8, ["is-open"]);
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
});
|
|
640
|
+
var SaveFilterModal_default = _sfc_main$3;
|
|
641
|
+
|
|
642
|
+
//#endregion
|
|
643
|
+
//#region src/slices/saved_filter/ManagePresetsModal.vue
|
|
644
|
+
const _hoisted_1$2 = { class: "space-y-4" };
|
|
645
|
+
const _hoisted_2$2 = {
|
|
646
|
+
key: 0,
|
|
647
|
+
class: "text-base-content/70 text-sm"
|
|
648
|
+
};
|
|
649
|
+
const _hoisted_3$2 = {
|
|
650
|
+
key: 1,
|
|
651
|
+
class: "flex justify-center py-4"
|
|
652
|
+
};
|
|
653
|
+
const _hoisted_4$2 = {
|
|
654
|
+
key: 2,
|
|
655
|
+
class: "space-y-2"
|
|
656
|
+
};
|
|
657
|
+
const _hoisted_5$1 = ["onKeydown"];
|
|
658
|
+
const _hoisted_6$1 = ["disabled", "onClick"];
|
|
659
|
+
const _hoisted_7$1 = ["disabled"];
|
|
660
|
+
const _hoisted_8$1 = { class: "font-medium truncate flex-1 min-w-0" };
|
|
661
|
+
const _hoisted_9$1 = { class: "text-base-content/60 text-xs font-normal ml-1" };
|
|
662
|
+
const _hoisted_10$1 = { class: "flex gap-1 shrink-0" };
|
|
663
|
+
const _hoisted_11$1 = ["onClick"];
|
|
664
|
+
const _hoisted_12$1 = ["disabled", "onClick"];
|
|
665
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
666
|
+
__name: "ManagePresetsModal",
|
|
667
|
+
props: {
|
|
668
|
+
isOpen: { type: Boolean },
|
|
669
|
+
presets: {},
|
|
670
|
+
loading: { type: Boolean },
|
|
671
|
+
deleting: { type: Boolean },
|
|
672
|
+
renaming: { type: Boolean },
|
|
673
|
+
renamePreset: { type: Function }
|
|
674
|
+
},
|
|
675
|
+
emits: ["close", "delete"],
|
|
676
|
+
setup(__props, { emit: __emit }) {
|
|
677
|
+
const props = __props;
|
|
678
|
+
const emit = __emit;
|
|
679
|
+
const editingId = ref(null);
|
|
680
|
+
const editingName = ref("");
|
|
681
|
+
const renameInputRef = ref(null);
|
|
682
|
+
function close() {
|
|
683
|
+
emit("close");
|
|
684
|
+
}
|
|
685
|
+
function startRename(preset) {
|
|
686
|
+
editingId.value = preset.id;
|
|
687
|
+
editingName.value = preset.name;
|
|
688
|
+
nextTick(() => renameInputRef.value?.focus());
|
|
689
|
+
}
|
|
690
|
+
function cancelRename() {
|
|
691
|
+
editingId.value = null;
|
|
692
|
+
editingName.value = "";
|
|
693
|
+
}
|
|
694
|
+
async function saveRename(presetId) {
|
|
695
|
+
const name = editingName.value.trim();
|
|
696
|
+
if (!name) return;
|
|
697
|
+
if (await props.renamePreset(presetId, name)) cancelRename();
|
|
698
|
+
}
|
|
699
|
+
function handleDelete(preset) {
|
|
700
|
+
emit("delete", preset);
|
|
701
|
+
}
|
|
702
|
+
watch(() => props.isOpen, (open) => {
|
|
703
|
+
if (!open) cancelRename();
|
|
704
|
+
});
|
|
705
|
+
return (_ctx, _cache) => {
|
|
706
|
+
return openBlock(), createBlock(BaseModal_default, {
|
|
707
|
+
"is-open": __props.isOpen,
|
|
708
|
+
title: "Manage Filter Presets",
|
|
709
|
+
onClose: close
|
|
710
|
+
}, {
|
|
711
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_1$2, [__props.presets.length === 0 && !__props.loading ? (openBlock(), createElementBlock("p", _hoisted_2$2, " No saved presets yet. Set filters, then use \"Save current filters\" in the Presets menu. ")) : __props.loading ? (openBlock(), createElementBlock("div", _hoisted_3$2, [..._cache[1] || (_cache[1] = [createElementVNode("span", { class: "loading loading-spinner loading-md" }, null, -1)])])) : (openBlock(), createElementBlock("ul", _hoisted_4$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.presets, (preset) => {
|
|
712
|
+
return openBlock(), createElementBlock("li", {
|
|
713
|
+
key: preset.id,
|
|
714
|
+
class: "flex items-center gap-2 p-2 rounded-lg bg-base-200"
|
|
715
|
+
}, [editingId.value === preset.id ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
716
|
+
withDirectives(createElementVNode("input", {
|
|
717
|
+
ref_for: true,
|
|
718
|
+
ref_key: "renameInputRef",
|
|
719
|
+
ref: renameInputRef,
|
|
720
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editingName.value = $event),
|
|
721
|
+
type: "text",
|
|
722
|
+
class: "input input-sm input-bordered flex-1 min-w-0",
|
|
723
|
+
maxlength: "100",
|
|
724
|
+
placeholder: "Preset name",
|
|
725
|
+
onKeydown: [withKeys(($event) => saveRename(preset.id), ["enter"]), withKeys(cancelRename, ["escape"])]
|
|
726
|
+
}, null, 40, _hoisted_5$1), [[vModelText, editingName.value]]),
|
|
727
|
+
createElementVNode("button", {
|
|
728
|
+
type: "button",
|
|
729
|
+
class: "btn btn-sm btn-primary shrink-0",
|
|
730
|
+
disabled: __props.renaming || !editingName.value.trim(),
|
|
731
|
+
onClick: ($event) => saveRename(preset.id)
|
|
732
|
+
}, toDisplayString(__props.renaming ? "..." : "Save"), 9, _hoisted_6$1),
|
|
733
|
+
createElementVNode("button", {
|
|
734
|
+
type: "button",
|
|
735
|
+
class: "btn btn-sm btn-ghost shrink-0",
|
|
736
|
+
disabled: __props.renaming,
|
|
737
|
+
onClick: cancelRename
|
|
738
|
+
}, " Cancel ", 8, _hoisted_7$1)
|
|
739
|
+
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createElementVNode("span", _hoisted_8$1, [createTextVNode(toDisplayString(preset.name) + " ", 1), createElementVNode("span", _hoisted_9$1, " (" + toDisplayString(Object.keys(preset.filters || {}).length) + ") ", 1)]), createElementVNode("div", _hoisted_10$1, [createElementVNode("button", {
|
|
740
|
+
type: "button",
|
|
741
|
+
class: "btn btn-sm btn-ghost",
|
|
742
|
+
title: "Rename",
|
|
743
|
+
onClick: ($event) => startRename(preset)
|
|
744
|
+
}, [..._cache[2] || (_cache[2] = [createElementVNode("svg", {
|
|
745
|
+
class: "w-4 h-4",
|
|
746
|
+
fill: "none",
|
|
747
|
+
stroke: "currentColor",
|
|
748
|
+
viewBox: "0 0 24 24"
|
|
749
|
+
}, [createElementVNode("path", {
|
|
750
|
+
"stroke-linecap": "round",
|
|
751
|
+
"stroke-linejoin": "round",
|
|
752
|
+
"stroke-width": "2",
|
|
753
|
+
d: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"
|
|
754
|
+
})], -1)])], 8, _hoisted_11$1), createElementVNode("button", {
|
|
755
|
+
type: "button",
|
|
756
|
+
class: "btn btn-sm btn-ghost text-error",
|
|
757
|
+
title: "Delete",
|
|
758
|
+
disabled: __props.deleting,
|
|
759
|
+
onClick: ($event) => handleDelete(preset)
|
|
760
|
+
}, [..._cache[3] || (_cache[3] = [createElementVNode("svg", {
|
|
761
|
+
class: "w-4 h-4",
|
|
762
|
+
fill: "none",
|
|
763
|
+
stroke: "currentColor",
|
|
764
|
+
viewBox: "0 0 24 24"
|
|
765
|
+
}, [createElementVNode("path", {
|
|
766
|
+
"stroke-linecap": "round",
|
|
767
|
+
"stroke-linejoin": "round",
|
|
768
|
+
"stroke-width": "2",
|
|
769
|
+
d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
|
770
|
+
})], -1)])], 8, _hoisted_12$1)])], 64))]);
|
|
771
|
+
}), 128))])), createElementVNode("div", { class: "flex justify-end pt-2" }, [createElementVNode("button", {
|
|
772
|
+
type: "button",
|
|
773
|
+
class: "btn btn-ghost",
|
|
774
|
+
onClick: close
|
|
775
|
+
}, " Close ")])])]),
|
|
776
|
+
_: 1
|
|
777
|
+
}, 8, ["is-open"]);
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
var ManagePresetsModal_default = _sfc_main$2;
|
|
782
|
+
|
|
783
|
+
//#endregion
|
|
784
|
+
//#region src/slices/saved_filter/PresetsModal.vue
|
|
785
|
+
const _hoisted_1$1 = { class: "space-y-4" };
|
|
786
|
+
const _hoisted_2$1 = { key: 0 };
|
|
787
|
+
const _hoisted_3$1 = { class: "space-y-2" };
|
|
788
|
+
const _hoisted_4$1 = ["onKeydown"];
|
|
789
|
+
const _hoisted_5 = ["disabled", "onClick"];
|
|
790
|
+
const _hoisted_6 = ["disabled"];
|
|
791
|
+
const _hoisted_7 = ["onClick"];
|
|
792
|
+
const _hoisted_8 = { class: "text-base-content/60 text-xs font-normal ml-1" };
|
|
793
|
+
const _hoisted_9 = { class: "flex gap-1 shrink-0" };
|
|
794
|
+
const _hoisted_10 = [
|
|
795
|
+
"title",
|
|
796
|
+
"disabled",
|
|
797
|
+
"onClick"
|
|
798
|
+
];
|
|
799
|
+
const _hoisted_11 = ["fill"];
|
|
800
|
+
const _hoisted_12 = ["onClick"];
|
|
801
|
+
const _hoisted_13 = ["disabled", "onClick"];
|
|
802
|
+
const _hoisted_14 = {
|
|
803
|
+
key: 2,
|
|
804
|
+
class: "flex justify-center py-2"
|
|
805
|
+
};
|
|
806
|
+
const _hoisted_15 = {
|
|
807
|
+
key: 3,
|
|
808
|
+
class: "space-y-2"
|
|
809
|
+
};
|
|
810
|
+
const _hoisted_16 = { class: "flex gap-2" };
|
|
811
|
+
const _hoisted_17 = ["disabled"];
|
|
812
|
+
const _hoisted_18 = ["disabled"];
|
|
813
|
+
const _hoisted_19 = ["disabled", "title"];
|
|
814
|
+
const _hoisted_20 = {
|
|
815
|
+
key: 0,
|
|
816
|
+
class: "text-base-content/60 text-xs"
|
|
817
|
+
};
|
|
818
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
819
|
+
__name: "PresetsModal",
|
|
820
|
+
props: {
|
|
821
|
+
isOpen: { type: Boolean },
|
|
822
|
+
presets: {},
|
|
823
|
+
loading: { type: Boolean },
|
|
824
|
+
creating: { type: Boolean },
|
|
825
|
+
deleting: { type: Boolean },
|
|
826
|
+
renaming: { type: Boolean },
|
|
827
|
+
hasFilters: { type: Boolean },
|
|
828
|
+
activePreset: {},
|
|
829
|
+
applyPreset: { type: Function },
|
|
830
|
+
saveCurrentFilters: { type: Function },
|
|
831
|
+
renamePreset: { type: Function },
|
|
832
|
+
isPinned: { type: Function },
|
|
833
|
+
togglePin: { type: Function },
|
|
834
|
+
canPinMore: { type: Boolean },
|
|
835
|
+
maxPinned: {}
|
|
836
|
+
},
|
|
837
|
+
emits: [
|
|
838
|
+
"close",
|
|
839
|
+
"delete",
|
|
840
|
+
"rename"
|
|
841
|
+
],
|
|
842
|
+
setup(__props, { emit: __emit }) {
|
|
843
|
+
const props = __props;
|
|
844
|
+
const maxPinned = computed(() => props.maxPinned ?? 5);
|
|
845
|
+
function handleTogglePin(preset) {
|
|
846
|
+
props.togglePin(preset);
|
|
847
|
+
}
|
|
848
|
+
const emit = __emit;
|
|
849
|
+
const canSaveMore = computed(() => props.presets.length < MAX_PRESETS_PER_CONTEXT);
|
|
850
|
+
const editingId = ref(null);
|
|
851
|
+
const editingName = ref("");
|
|
852
|
+
const renameInputRef = ref(null);
|
|
853
|
+
const showSaveForm = ref(false);
|
|
854
|
+
const saveName = ref("");
|
|
855
|
+
const saveInputRef = ref(null);
|
|
856
|
+
function close() {
|
|
857
|
+
emit("close");
|
|
858
|
+
}
|
|
859
|
+
function applyAndClose(preset) {
|
|
860
|
+
props.applyPreset(preset);
|
|
861
|
+
close();
|
|
862
|
+
}
|
|
863
|
+
function startRename(preset) {
|
|
864
|
+
editingId.value = preset.id;
|
|
865
|
+
editingName.value = preset.name;
|
|
866
|
+
nextTick(() => renameInputRef.value?.focus());
|
|
867
|
+
}
|
|
868
|
+
function cancelRename() {
|
|
869
|
+
editingId.value = null;
|
|
870
|
+
editingName.value = "";
|
|
871
|
+
}
|
|
872
|
+
async function saveRename(presetId) {
|
|
873
|
+
const name = editingName.value.trim();
|
|
874
|
+
if (!name) return;
|
|
875
|
+
const result = await props.renamePreset(presetId, name);
|
|
876
|
+
if (result) {
|
|
877
|
+
emit("rename", result);
|
|
878
|
+
cancelRename();
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
function handleDelete(preset) {
|
|
882
|
+
emit("delete", preset);
|
|
883
|
+
}
|
|
884
|
+
function startSave() {
|
|
885
|
+
if (props.hasFilters && canSaveMore.value) {
|
|
886
|
+
showSaveForm.value = true;
|
|
887
|
+
saveName.value = "";
|
|
888
|
+
nextTick(() => saveInputRef.value?.focus());
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
function cancelSave() {
|
|
892
|
+
showSaveForm.value = false;
|
|
893
|
+
saveName.value = "";
|
|
894
|
+
}
|
|
895
|
+
async function submitSave() {
|
|
896
|
+
const name = saveName.value.trim();
|
|
897
|
+
if (!name) return;
|
|
898
|
+
if (await props.saveCurrentFilters(name)) {
|
|
899
|
+
cancelSave();
|
|
900
|
+
close();
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
watch(() => props.isOpen, (open) => {
|
|
904
|
+
if (!open) {
|
|
905
|
+
cancelRename();
|
|
906
|
+
cancelSave();
|
|
907
|
+
}
|
|
908
|
+
});
|
|
909
|
+
return (_ctx, _cache) => {
|
|
910
|
+
return openBlock(), createBlock(BaseModal_default, {
|
|
911
|
+
"is-open": __props.isOpen,
|
|
912
|
+
title: "Filter Presets",
|
|
913
|
+
onClose: close
|
|
914
|
+
}, {
|
|
915
|
+
default: withCtx(() => [createElementVNode("div", _hoisted_1$1, [
|
|
916
|
+
createCommentVNode(" Preset list: apply (click name), rename, delete "),
|
|
917
|
+
__props.presets.length > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$1, [_cache[5] || (_cache[5] = createElementVNode("p", { class: "text-xs font-medium text-base-content/60 uppercase tracking-wide mb-2" }, " Apply preset ", -1)), createElementVNode("ul", _hoisted_3$1, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.presets, (preset) => {
|
|
918
|
+
return openBlock(), createElementBlock("li", {
|
|
919
|
+
key: preset.id,
|
|
920
|
+
class: "flex items-center gap-2 p-2 rounded-lg bg-base-200"
|
|
921
|
+
}, [editingId.value === preset.id ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
922
|
+
withDirectives(createElementVNode("input", {
|
|
923
|
+
ref_for: true,
|
|
924
|
+
ref_key: "renameInputRef",
|
|
925
|
+
ref: renameInputRef,
|
|
926
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => editingName.value = $event),
|
|
927
|
+
type: "text",
|
|
928
|
+
class: "input input-sm input-bordered flex-1 min-w-0",
|
|
929
|
+
maxlength: "100",
|
|
930
|
+
placeholder: "Preset name",
|
|
931
|
+
onKeydown: [withKeys(($event) => saveRename(preset.id), ["enter"]), withKeys(cancelRename, ["escape"])]
|
|
932
|
+
}, null, 40, _hoisted_4$1), [[vModelText, editingName.value]]),
|
|
933
|
+
createElementVNode("button", {
|
|
934
|
+
type: "button",
|
|
935
|
+
class: "btn btn-sm btn-primary shrink-0",
|
|
936
|
+
disabled: __props.renaming || !editingName.value.trim(),
|
|
937
|
+
onClick: ($event) => saveRename(preset.id)
|
|
938
|
+
}, toDisplayString(__props.renaming ? "..." : "Save"), 9, _hoisted_5),
|
|
939
|
+
createElementVNode("button", {
|
|
940
|
+
type: "button",
|
|
941
|
+
class: "btn btn-sm btn-ghost shrink-0",
|
|
942
|
+
disabled: __props.renaming,
|
|
943
|
+
onClick: cancelRename
|
|
944
|
+
}, " Cancel ", 8, _hoisted_6)
|
|
945
|
+
], 64)) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createElementVNode("button", {
|
|
946
|
+
type: "button",
|
|
947
|
+
class: normalizeClass(["flex-1 min-w-0 text-left font-medium truncate rounded px-2 py-1 -mx-2 -my-1 hover:bg-base-300", { "bg-primary/10": preset.id === __props.activePreset?.id }]),
|
|
948
|
+
onClick: ($event) => applyAndClose(preset)
|
|
949
|
+
}, [createTextVNode(toDisplayString(preset.name) + " ", 1), createElementVNode("span", _hoisted_8, " (" + toDisplayString(Object.keys(preset.filters || {}).length) + ") ", 1)], 10, _hoisted_7), createElementVNode("div", _hoisted_9, [
|
|
950
|
+
createElementVNode("button", {
|
|
951
|
+
type: "button",
|
|
952
|
+
class: "btn btn-sm btn-ghost",
|
|
953
|
+
title: __props.isPinned(preset.id) ? "Unpin from favorites" : __props.canPinMore ? "Pin to favorites (home + sidebar)" : `Maximum ${maxPinned.value} pinned`,
|
|
954
|
+
disabled: !__props.canPinMore && !__props.isPinned(preset.id),
|
|
955
|
+
onClick: withModifiers(($event) => handleTogglePin(preset), ["stop"])
|
|
956
|
+
}, [(openBlock(), createElementBlock("svg", {
|
|
957
|
+
class: normalizeClass(["w-4 h-4", { "text-primary": __props.isPinned(preset.id) }]),
|
|
958
|
+
fill: __props.isPinned(preset.id) ? "currentColor" : "none",
|
|
959
|
+
stroke: "currentColor",
|
|
960
|
+
viewBox: "0 0 24 24"
|
|
961
|
+
}, [..._cache[2] || (_cache[2] = [createElementVNode("path", {
|
|
962
|
+
"stroke-linecap": "round",
|
|
963
|
+
"stroke-linejoin": "round",
|
|
964
|
+
"stroke-width": "2",
|
|
965
|
+
d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z"
|
|
966
|
+
}, null, -1)])], 10, _hoisted_11))], 8, _hoisted_10),
|
|
967
|
+
createElementVNode("button", {
|
|
968
|
+
type: "button",
|
|
969
|
+
class: "btn btn-sm btn-ghost",
|
|
970
|
+
title: "Rename",
|
|
971
|
+
onClick: withModifiers(($event) => startRename(preset), ["stop"])
|
|
972
|
+
}, [..._cache[3] || (_cache[3] = [createElementVNode("svg", {
|
|
973
|
+
class: "w-4 h-4",
|
|
974
|
+
fill: "none",
|
|
975
|
+
stroke: "currentColor",
|
|
976
|
+
viewBox: "0 0 24 24"
|
|
977
|
+
}, [createElementVNode("path", {
|
|
978
|
+
"stroke-linecap": "round",
|
|
979
|
+
"stroke-linejoin": "round",
|
|
980
|
+
"stroke-width": "2",
|
|
981
|
+
d: "M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z"
|
|
982
|
+
})], -1)])], 8, _hoisted_12),
|
|
983
|
+
createElementVNode("button", {
|
|
984
|
+
type: "button",
|
|
985
|
+
class: "btn btn-sm btn-ghost text-error",
|
|
986
|
+
title: "Delete",
|
|
987
|
+
disabled: __props.deleting,
|
|
988
|
+
onClick: withModifiers(($event) => handleDelete(preset), ["stop"])
|
|
989
|
+
}, [..._cache[4] || (_cache[4] = [createElementVNode("svg", {
|
|
990
|
+
class: "w-4 h-4",
|
|
991
|
+
fill: "none",
|
|
992
|
+
stroke: "currentColor",
|
|
993
|
+
viewBox: "0 0 24 24"
|
|
994
|
+
}, [createElementVNode("path", {
|
|
995
|
+
"stroke-linecap": "round",
|
|
996
|
+
"stroke-linejoin": "round",
|
|
997
|
+
"stroke-width": "2",
|
|
998
|
+
d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"
|
|
999
|
+
})], -1)])], 8, _hoisted_13)
|
|
1000
|
+
])], 64))]);
|
|
1001
|
+
}), 128))])])) : !__props.loading ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createCommentVNode(" Empty state "), _cache[6] || (_cache[6] = createElementVNode("p", { class: "text-base-content/70 text-sm" }, " No presets yet. Set filters, then save below. ", -1))], 2112)) : createCommentVNode("v-if", true),
|
|
1002
|
+
__props.loading ? (openBlock(), createElementBlock("div", _hoisted_14, [..._cache[7] || (_cache[7] = [createElementVNode("span", { class: "loading loading-spinner loading-md" }, null, -1)])])) : createCommentVNode("v-if", true),
|
|
1003
|
+
_cache[11] || (_cache[11] = createElementVNode("div", { class: "divider my-2" }, null, -1)),
|
|
1004
|
+
createCommentVNode(" Save current filters: inline form when saving "),
|
|
1005
|
+
showSaveForm.value ? (openBlock(), createElementBlock("div", _hoisted_15, [_cache[8] || (_cache[8] = createElementVNode("label", { class: "label py-0" }, [createElementVNode("span", { class: "label-text" }, "Preset name")], -1)), createElementVNode("div", _hoisted_16, [
|
|
1006
|
+
withDirectives(createElementVNode("input", {
|
|
1007
|
+
ref_key: "saveInputRef",
|
|
1008
|
+
ref: saveInputRef,
|
|
1009
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => saveName.value = $event),
|
|
1010
|
+
type: "text",
|
|
1011
|
+
placeholder: "e.g. My Sales Escalations",
|
|
1012
|
+
class: "input input-sm input-bordered flex-1",
|
|
1013
|
+
maxlength: "100",
|
|
1014
|
+
onKeydown: [withKeys(submitSave, ["enter"]), withKeys(cancelSave, ["escape"])]
|
|
1015
|
+
}, null, 544), [[vModelText, saveName.value]]),
|
|
1016
|
+
createElementVNode("button", {
|
|
1017
|
+
type: "button",
|
|
1018
|
+
class: "btn btn-sm btn-primary",
|
|
1019
|
+
disabled: __props.creating || !saveName.value.trim(),
|
|
1020
|
+
onClick: submitSave
|
|
1021
|
+
}, toDisplayString(__props.creating ? "Saving..." : "Save"), 9, _hoisted_17),
|
|
1022
|
+
createElementVNode("button", {
|
|
1023
|
+
type: "button",
|
|
1024
|
+
class: "btn btn-sm btn-ghost",
|
|
1025
|
+
disabled: __props.creating,
|
|
1026
|
+
onClick: cancelSave
|
|
1027
|
+
}, " Cancel ", 8, _hoisted_18)
|
|
1028
|
+
])])) : (openBlock(), createElementBlock("button", {
|
|
1029
|
+
key: 4,
|
|
1030
|
+
type: "button",
|
|
1031
|
+
class: "btn btn-ghost btn-sm btn-block justify-start gap-2",
|
|
1032
|
+
disabled: !__props.hasFilters || __props.creating || !canSaveMore.value,
|
|
1033
|
+
title: !canSaveMore.value ? `Maximum ${unref(MAX_PRESETS_PER_CONTEXT)} presets per page. Delete one to save a new preset.` : void 0,
|
|
1034
|
+
onClick: startSave
|
|
1035
|
+
}, [
|
|
1036
|
+
_cache[9] || (_cache[9] = createElementVNode("svg", {
|
|
1037
|
+
class: "w-4 h-4 shrink-0",
|
|
1038
|
+
fill: "none",
|
|
1039
|
+
stroke: "currentColor",
|
|
1040
|
+
viewBox: "0 0 24 24"
|
|
1041
|
+
}, [createElementVNode("path", {
|
|
1042
|
+
"stroke-linecap": "round",
|
|
1043
|
+
"stroke-linejoin": "round",
|
|
1044
|
+
"stroke-width": "2",
|
|
1045
|
+
d: "M12 4v16m8-8v8H4V4h8m0 0l4 4-4 4"
|
|
1046
|
+
})], -1)),
|
|
1047
|
+
_cache[10] || (_cache[10] = createTextVNode(" Save current filters ", -1)),
|
|
1048
|
+
!canSaveMore.value ? (openBlock(), createElementBlock("span", _hoisted_20, "(max " + toDisplayString(unref(MAX_PRESETS_PER_CONTEXT)) + ")", 1)) : createCommentVNode("v-if", true)
|
|
1049
|
+
], 8, _hoisted_19)),
|
|
1050
|
+
createElementVNode("div", { class: "flex justify-end pt-2" }, [createElementVNode("button", {
|
|
1051
|
+
type: "button",
|
|
1052
|
+
class: "btn btn-ghost",
|
|
1053
|
+
onClick: close
|
|
1054
|
+
}, " Close ")])
|
|
1055
|
+
])]),
|
|
1056
|
+
_: 1
|
|
1057
|
+
}, 8, ["is-open"]);
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
var PresetsModal_default = _sfc_main$1;
|
|
1062
|
+
|
|
1063
|
+
//#endregion
|
|
1064
|
+
//#region src/slices/saved_filter/SavedFilterPresets.vue
|
|
1065
|
+
const _hoisted_1 = { class: "flex items-center gap-2 flex-wrap" };
|
|
1066
|
+
const _hoisted_2 = {
|
|
1067
|
+
key: 0,
|
|
1068
|
+
class: "badge badge-primary badge-lg gap-1 pr-1"
|
|
1069
|
+
};
|
|
1070
|
+
const _hoisted_3 = { class: "truncate max-w-[8rem] sm:max-w-[12rem]" };
|
|
1071
|
+
const _hoisted_4 = ["disabled", "title"];
|
|
1072
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
1073
|
+
__name: "SavedFilterPresets",
|
|
1074
|
+
props: {
|
|
1075
|
+
presets: {},
|
|
1076
|
+
presetsLoading: { type: Boolean },
|
|
1077
|
+
creating: { type: Boolean },
|
|
1078
|
+
deleting: { type: Boolean },
|
|
1079
|
+
renaming: { type: Boolean },
|
|
1080
|
+
hasFilters: { type: Boolean },
|
|
1081
|
+
activePreset: {},
|
|
1082
|
+
applyPreset: { type: Function },
|
|
1083
|
+
clearPreset: { type: Function },
|
|
1084
|
+
saveCurrentFilters: { type: Function },
|
|
1085
|
+
renamePreset: { type: Function },
|
|
1086
|
+
removePreset: { type: Function }
|
|
1087
|
+
},
|
|
1088
|
+
setup(__props) {
|
|
1089
|
+
const pinnedPresets = useInjectedPinnedPresets();
|
|
1090
|
+
const props = __props;
|
|
1091
|
+
const showPresetsModal = ref(false);
|
|
1092
|
+
const showDeleteConfirm = ref(false);
|
|
1093
|
+
const presetToDelete = ref(null);
|
|
1094
|
+
function handleClearPreset() {
|
|
1095
|
+
props.clearPreset();
|
|
1096
|
+
}
|
|
1097
|
+
function handleDelete(preset) {
|
|
1098
|
+
presetToDelete.value = preset;
|
|
1099
|
+
showDeleteConfirm.value = true;
|
|
1100
|
+
}
|
|
1101
|
+
async function confirmDelete() {
|
|
1102
|
+
if (!presetToDelete.value) return;
|
|
1103
|
+
pinnedPresets.unpinPreset(presetToDelete.value.id);
|
|
1104
|
+
await props.removePreset(presetToDelete.value.id);
|
|
1105
|
+
presetToDelete.value = null;
|
|
1106
|
+
showDeleteConfirm.value = false;
|
|
1107
|
+
}
|
|
1108
|
+
async function handleRename(preset) {
|
|
1109
|
+
pinnedPresets.updatePinnedPreset(preset.id, { name: preset.name });
|
|
1110
|
+
await pinnedPresets.refetchPinned?.();
|
|
1111
|
+
}
|
|
1112
|
+
return (_ctx, _cache) => {
|
|
1113
|
+
return openBlock(), createElementBlock("div", _hoisted_1, [
|
|
1114
|
+
createCommentVNode(" Active preset chip: shows when a preset is applied, with clear (×) "),
|
|
1115
|
+
props.activePreset ? (openBlock(), createElementBlock("div", _hoisted_2, [createElementVNode("span", _hoisted_3, toDisplayString(props.activePreset.name), 1), createElementVNode("button", {
|
|
1116
|
+
type: "button",
|
|
1117
|
+
class: "btn btn-ghost btn-xs btn-circle",
|
|
1118
|
+
"aria-label": "Clear preset",
|
|
1119
|
+
onClick: handleClearPreset
|
|
1120
|
+
}, [..._cache[4] || (_cache[4] = [createElementVNode("svg", {
|
|
1121
|
+
class: "w-3 h-3",
|
|
1122
|
+
fill: "none",
|
|
1123
|
+
stroke: "currentColor",
|
|
1124
|
+
viewBox: "0 0 24 24"
|
|
1125
|
+
}, [createElementVNode("path", {
|
|
1126
|
+
"stroke-linecap": "round",
|
|
1127
|
+
"stroke-linejoin": "round",
|
|
1128
|
+
"stroke-width": "2",
|
|
1129
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
1130
|
+
})], -1)])])])) : createCommentVNode("v-if", true),
|
|
1131
|
+
createCommentVNode(" Presets button: opens modal with everything "),
|
|
1132
|
+
createElementVNode("button", {
|
|
1133
|
+
type: "button",
|
|
1134
|
+
class: "btn btn-sm btn-ghost",
|
|
1135
|
+
disabled: props.presetsLoading,
|
|
1136
|
+
title: props.presets.length ? "Apply, save, or manage presets" : "No presets saved",
|
|
1137
|
+
onClick: _cache[0] || (_cache[0] = ($event) => showPresetsModal.value = true)
|
|
1138
|
+
}, [..._cache[5] || (_cache[5] = [createElementVNode("svg", {
|
|
1139
|
+
class: "w-4 h-4",
|
|
1140
|
+
fill: "none",
|
|
1141
|
+
stroke: "currentColor",
|
|
1142
|
+
viewBox: "0 0 24 24"
|
|
1143
|
+
}, [createElementVNode("path", {
|
|
1144
|
+
"stroke-linecap": "round",
|
|
1145
|
+
"stroke-linejoin": "round",
|
|
1146
|
+
"stroke-width": "2",
|
|
1147
|
+
d: "M3 4a1 1 0 011-1h16a1 1 0 011 1v2.586a1 1 0 01-.293.707l-6.414 6.414a1 1 0 00-.293.707V17l-4 4v-6.586a1 1 0 00-.293-.707L3.293 7.293A1 1 0 013 6.586V4z"
|
|
1148
|
+
})], -1), createTextVNode(" Presets ", -1)])], 8, _hoisted_4),
|
|
1149
|
+
createCommentVNode(" Delete confirmation modal "),
|
|
1150
|
+
createVNode(ConfirmDialog_default, {
|
|
1151
|
+
modelValue: showDeleteConfirm.value,
|
|
1152
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => showDeleteConfirm.value = $event),
|
|
1153
|
+
title: "Delete preset?",
|
|
1154
|
+
"confirm-text": "Delete",
|
|
1155
|
+
"cancel-text": "Cancel",
|
|
1156
|
+
"processing-text": "Deleting...",
|
|
1157
|
+
"confirm-button-class": "btn-error",
|
|
1158
|
+
"is-processing": props.deleting,
|
|
1159
|
+
onConfirm: confirmDelete,
|
|
1160
|
+
onCancel: _cache[2] || (_cache[2] = ($event) => presetToDelete.value = null)
|
|
1161
|
+
}, {
|
|
1162
|
+
message: withCtx(() => [createElementVNode("p", null, " Are you sure you want to delete \"" + toDisplayString(presetToDelete.value?.name) + "\"? This cannot be undone. ", 1)]),
|
|
1163
|
+
_: 1
|
|
1164
|
+
}, 8, ["modelValue", "is-processing"]),
|
|
1165
|
+
createCommentVNode(" Single Presets modal: apply, save, rename, delete "),
|
|
1166
|
+
createVNode(PresetsModal_default, {
|
|
1167
|
+
"is-open": showPresetsModal.value,
|
|
1168
|
+
presets: props.presets,
|
|
1169
|
+
loading: props.presetsLoading,
|
|
1170
|
+
creating: props.creating,
|
|
1171
|
+
deleting: props.deleting,
|
|
1172
|
+
renaming: props.renaming,
|
|
1173
|
+
"has-filters": props.hasFilters,
|
|
1174
|
+
"active-preset": props.activePreset,
|
|
1175
|
+
"apply-preset": props.applyPreset,
|
|
1176
|
+
"save-current-filters": props.saveCurrentFilters,
|
|
1177
|
+
"rename-preset": props.renamePreset,
|
|
1178
|
+
"is-pinned": unref(pinnedPresets).isPinned,
|
|
1179
|
+
"toggle-pin": unref(pinnedPresets).togglePin,
|
|
1180
|
+
"can-pin-more": unref(pinnedPresets).canPinMore.value,
|
|
1181
|
+
"max-pinned": unref(pinnedPresets).maxPinned,
|
|
1182
|
+
onClose: _cache[3] || (_cache[3] = ($event) => showPresetsModal.value = false),
|
|
1183
|
+
onDelete: handleDelete,
|
|
1184
|
+
onRename: handleRename
|
|
1185
|
+
}, null, 8, [
|
|
1186
|
+
"is-open",
|
|
1187
|
+
"presets",
|
|
1188
|
+
"loading",
|
|
1189
|
+
"creating",
|
|
1190
|
+
"deleting",
|
|
1191
|
+
"renaming",
|
|
1192
|
+
"has-filters",
|
|
1193
|
+
"active-preset",
|
|
1194
|
+
"apply-preset",
|
|
1195
|
+
"save-current-filters",
|
|
1196
|
+
"rename-preset",
|
|
1197
|
+
"is-pinned",
|
|
1198
|
+
"toggle-pin",
|
|
1199
|
+
"can-pin-more",
|
|
1200
|
+
"max-pinned"
|
|
1201
|
+
])
|
|
1202
|
+
]);
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
var SavedFilterPresets_default = _sfc_main;
|
|
1207
|
+
|
|
1208
|
+
//#endregion
|
|
1209
|
+
export { useSavedFilters as a, buildQueryWithFilters as c, serializeFiltersToQueryParams as d, PINNED_PRESETS_KEY as f, BaseModal_default as g, MS as h, savedFilterRoutes as i, deserializeFiltersFromQueryParams as l, usePinnedPresets as m, ManagePresetsModal_default as n, createLastUsedPresetGuard as o, useInjectedPinnedPresets as p, SaveFilterModal_default as r, getLastUsedPresetRedirect as s, SavedFilterPresets_default as t, extractFiltersFromQuery as u };
|
|
1210
|
+
//# sourceMappingURL=saved_filter-CfzH0BzK.js.map
|