@opengis/admin 0.1.2 → 0.1.4
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/add-page-D6D_vCdT.js +94 -0
- package/dist/{admin-interface-vPkHXzQK.js → admin-interface-BpAoXL6Y.js} +236 -208
- package/dist/{admin-view-BYF4ITZY.js → admin-view-Ctnb3YHc.js} +10 -10
- package/dist/admin.js +1 -1
- package/dist/admin.umd.cjs +618 -25
- package/dist/card-page-CDUWky8v.js +133 -0
- package/dist/{card-view-CjZRvfqy.js → card-view-BdtKFM_Q.js} +1 -1
- package/dist/edit-page-Bl7TSfk5.js +104 -0
- package/dist/import-file-bAV0TNST.js +29762 -0
- package/dist/style.css +1 -1
- package/package.json +18 -5
- package/plugin.js +1 -1
- package/server/plugins/vite.js +13 -8
- package/server/routes/data/controllers/cardData.js +1 -1
- package/server/routes/data/controllers/funcs/getFilterSQL/index.js +82 -0
- package/server/routes/data/controllers/funcs/getFilterSQL/util/formatValue.js +142 -0
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getCustomQuery.js +13 -0
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getFilterQuery.js +67 -0
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getOptimizedQuery.js +12 -0
- package/server/routes/data/controllers/funcs/getFilterSQL/util/getTableSql.js +34 -0
- package/server/routes/data/controllers/tableData.js +12 -31
- package/server/routes/data/controllers/tableFilter.js +1 -1
- package/server/routes/data/controllers/utils/assignTokens.js +31 -0
- package/server/routes/data/index.mjs +1 -1
- package/server/routes/templates/controllers/getTemplate.js +2 -4
- package/server/templates/cls/itree.recrzone_category.json +74 -0
- package/dist/add-page-C-msiPrU.js +0 -64
- package/dist/card-page-HOwuHNjV.js +0 -49
- package/dist/edit-page-7yrRusn4.js +0 -58
- package/dist/form-TrZSpRSC.js +0 -38
- package/dist/import-file-DPHo57R5.js +0 -3726
- package/server/routes/data/controllers/metaFormat/getSelectVal.js +0 -19
- package/server/routes/data/controllers/metaFormat/index.js +0 -29
- package/server/routes/templates/funcs/addTempateFolder.js +0 -47
- package/server/routes/templates/funcs/getTemplate.js +0 -70
- package/server/routes/templates/funcs/getTemplatePath.js +0 -39
- package/server/routes/templates/funcs/loadTemplate.js +0 -1
- package/server/routes/templates/funcs/loadTemplateDir.js +0 -1
- package/server/routes/templates/funcs/loadTemplatePath.js +0 -1
- package/server/templates/interface/management.user_group.html +0 -1
- package/server/templates/interface/management.user_group.json +0 -10
- package/server/templates/interface/management.users.html +0 -1
- package/server/templates/interface/management.users.json +0 -10
- package/server/templates/map/dgm_level_line.xml +0 -52
- package/server/templates/pt/admin-menu-pt.html +0 -108
- package/server/templates/pt/management.user_group.table.pt.html +0 -127
- package/server/templates/pt/management.users.table.pt.html +0 -130
- package/server/templates/pt/table-standard-pt.html +0 -202
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.admin-wrapper[data-v-3a278cfb]{display:flex;height:100vh;align-items:start}
|
|
1
|
+
.map-popup__vertical[data-v-3f5a9aff]{overflow:auto;max-height:300px}.map-popup__vertical[data-v-3f5a9aff]::-webkit-scrollbar{width:6px;height:6px;background-color:#f5f5f5}.map-popup__vertical[data-v-3f5a9aff]::-webkit-scrollbar-thumb{border-radius:5px;background-color:#dedede}.map-popup__vertical[data-v-3f5a9aff]::-webkit-scrollbar-track{background-color:#f5f5f5}.map__popup-body[data-v-3f5a9aff]{table-layout:fixed;width:100%}.map__popup-body-item[data-v-3f5a9aff]:not(:last-child){border-bottom:1px solid #eeeeee}.map__popup-body-item td[data-v-3f5a9aff]{width:50%;word-wrap:break-word;text-align:start}.map__popup-body-item td[data-v-3f5a9aff]:first-child{font-weight:600}.popup-image[data-v-deb51e0a]{max-width:100%;max-height:220px;margin-bottom:10px;object-fit:contain}.maplibregl-ctrl-bottom-right,.maplibregl-popup-close-button{display:none}:root{--f-spinner-width: 36px;--f-spinner-height: 36px;--f-spinner-color-1: rgba(0, 0, 0, .1);--f-spinner-color-2: rgba(17, 24, 28, .8);--f-spinner-stroke: 2.75}.f-spinner{margin:auto;padding:0;width:var(--f-spinner-width);height:var(--f-spinner-height)}.f-spinner svg{width:100%;height:100%;vertical-align:top;animation:f-spinner-rotate 2s linear infinite}.f-spinner svg *{stroke-width:var(--f-spinner-stroke);fill:none}.f-spinner svg *:first-child{stroke:var(--f-spinner-color-1)}.f-spinner svg *:last-child{stroke:var(--f-spinner-color-2);animation:f-spinner-dash 2s ease-in-out infinite}@keyframes f-spinner-rotate{to{transform:rotate(360deg)}}@keyframes f-spinner-dash{0%{stroke-dasharray:1,150;stroke-dashoffset:0}50%{stroke-dasharray:90,150;stroke-dashoffset:-35}to{stroke-dasharray:90,150;stroke-dashoffset:-124}}.f-throwOutUp{animation:var(--f-throw-out-duration, .175s) ease-out both f-throwOutUp}.f-throwOutDown{animation:var(--f-throw-out-duration, .175s) ease-out both f-throwOutDown}@keyframes f-throwOutUp{to{transform:translate3d(0,calc(var(--f-throw-out-distance, 150px) * -1),0);opacity:0}}@keyframes f-throwOutDown{to{transform:translate3d(0,var(--f-throw-out-distance, 150px),0);opacity:0}}.f-zoomInUp{animation:var(--f-transition-duration, .2s) ease .1s both f-zoomInUp}.f-zoomOutDown{animation:var(--f-transition-duration, .2s) ease both f-zoomOutDown}@keyframes f-zoomInUp{0%{transform:scale(.975) translate3d(0,16px,0);opacity:0}to{transform:scale(1) translateZ(0);opacity:1}}@keyframes f-zoomOutDown{to{transform:scale(.975) translate3d(0,16px,0);opacity:0}}.f-fadeIn{animation:var(--f-transition-duration, .2s) var(--f-transition-easing, ease) var(--f-transition-delay, 0s) both f-fadeIn;z-index:2}.f-fadeOut{animation:var(--f-transition-duration, .2s) var(--f-transition-easing, ease) var(--f-transition-delay, 0s) both f-fadeOut;z-index:1}@keyframes f-fadeIn{0%{opacity:0}to{opacity:1}}@keyframes f-fadeOut{to{opacity:0}}.f-fadeFastIn{animation:var(--f-transition-duration, .2s) ease-out both f-fadeFastIn;z-index:2}.f-fadeFastOut{animation:var(--f-transition-duration, .1s) ease-out both f-fadeFastOut;z-index:2}@keyframes f-fadeFastIn{0%{opacity:.75}to{opacity:1}}@keyframes f-fadeFastOut{to{opacity:0}}.f-fadeSlowIn{animation:var(--f-transition-duration, .5s) ease both f-fadeSlowIn;z-index:2}.f-fadeSlowOut{animation:var(--f-transition-duration, .5s) ease both f-fadeSlowOut;z-index:1}@keyframes f-fadeSlowIn{0%{opacity:0}to{opacity:1}}@keyframes f-fadeSlowOut{to{opacity:0}}.f-crossfadeIn{animation:var(--f-transition-duration, .2s) ease-out both f-crossfadeIn;z-index:2}.f-crossfadeOut{animation:calc(var(--f-transition-duration, .2s)*.5) linear .1s both f-crossfadeOut;z-index:1}@keyframes f-crossfadeIn{0%{opacity:0}to{opacity:1}}@keyframes f-crossfadeOut{to{opacity:0}}.f-slideIn.from-next{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-slideInNext}.f-slideIn.from-prev{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-slideInPrev}.f-slideOut.to-next{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-slideOutNext}.f-slideOut.to-prev{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-slideOutPrev}@keyframes f-slideInPrev{0%{transform:translate(100%)}to{transform:translateZ(0)}}@keyframes f-slideInNext{0%{transform:translate(-100%)}to{transform:translateZ(0)}}@keyframes f-slideOutNext{to{transform:translate(-100%)}}@keyframes f-slideOutPrev{to{transform:translate(100%)}}.f-classicIn.from-next{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-classicInNext;z-index:2}.f-classicIn.from-prev{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-classicInPrev;z-index:2}.f-classicOut.to-next{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-classicOutNext;z-index:1}.f-classicOut.to-prev{animation:var(--f-transition-duration, .85s) cubic-bezier(.16,1,.3,1) f-classicOutPrev;z-index:1}@keyframes f-classicInNext{0%{transform:translate(-75px);opacity:0}to{transform:translateZ(0);opacity:1}}@keyframes f-classicInPrev{0%{transform:translate(75px);opacity:0}to{transform:translateZ(0);opacity:1}}@keyframes f-classicOutNext{to{transform:translate(-75px);opacity:0}}@keyframes f-classicOutPrev{to{transform:translate(75px);opacity:0}}:root{--f-button-width: 40px;--f-button-height: 40px;--f-button-border: 0;--f-button-border-radius: 0;--f-button-color: #374151;--f-button-bg: #f8f8f8;--f-button-hover-bg: #e0e0e0;--f-button-active-bg: #d0d0d0;--f-button-shadow: none;--f-button-transition: all .15s ease;--f-button-transform: none;--f-button-svg-width: 20px;--f-button-svg-height: 20px;--f-button-svg-stroke-width: 1.5;--f-button-svg-fill: none;--f-button-svg-filter: none;--f-button-svg-disabled-opacity: .65}.f-button{display:flex;justify-content:center;align-items:center;box-sizing:content-box;position:relative;margin:0;padding:0;width:var(--f-button-width);height:var(--f-button-height);border:var(--f-button-border);border-radius:var(--f-button-border-radius);color:var(--f-button-color);background:var(--f-button-bg);box-shadow:var(--f-button-shadow);pointer-events:all;cursor:pointer;transition:var(--f-button-transition)}@media (hover: hover){.f-button:hover:not([disabled]){color:var(--f-button-hover-color);background-color:var(--f-button-hover-bg)}}.f-button:active:not([disabled]){background-color:var(--f-button-active-bg)}.f-button:focus:not(:focus-visible){outline:none}.f-button:focus-visible{outline:none;box-shadow:inset 0 0 0 var(--f-button-outline, 2px) var(--f-button-outline-color, var(--f-button-color))}.f-button svg{width:var(--f-button-svg-width);height:var(--f-button-svg-height);fill:var(--f-button-svg-fill);stroke:currentColor;stroke-width:var(--f-button-svg-stroke-width);stroke-linecap:round;stroke-linejoin:round;transition:opacity .15s ease;transform:var(--f-button-transform);filter:var(--f-button-svg-filter);pointer-events:none}.f-button[disabled]{cursor:default}.f-button[disabled] svg{opacity:var(--f-button-svg-disabled-opacity)}.f-carousel__nav .f-button.is-prev,.f-carousel__nav .f-button.is-next,.fancybox__nav .f-button.is-prev,.fancybox__nav .f-button.is-next{position:absolute;z-index:1}.is-horizontal .f-carousel__nav .f-button.is-prev,.is-horizontal .f-carousel__nav .f-button.is-next,.is-horizontal .fancybox__nav .f-button.is-prev,.is-horizontal .fancybox__nav .f-button.is-next{top:50%;transform:translateY(-50%)}.is-horizontal .f-carousel__nav .f-button.is-prev,.is-horizontal .fancybox__nav .f-button.is-prev{left:var(--f-button-prev-pos)}.is-horizontal .f-carousel__nav .f-button.is-next,.is-horizontal .fancybox__nav .f-button.is-next{right:var(--f-button-next-pos)}.is-horizontal.is-rtl .f-carousel__nav .f-button.is-prev,.is-horizontal.is-rtl .fancybox__nav .f-button.is-prev{left:auto;right:var(--f-button-next-pos)}.is-horizontal.is-rtl .f-carousel__nav .f-button.is-next,.is-horizontal.is-rtl .fancybox__nav .f-button.is-next{right:auto;left:var(--f-button-prev-pos)}.is-vertical .f-carousel__nav .f-button.is-prev,.is-vertical .f-carousel__nav .f-button.is-next,.is-vertical .fancybox__nav .f-button.is-prev,.is-vertical .fancybox__nav .f-button.is-next{top:auto;left:50%;transform:translate(-50%)}.is-vertical .f-carousel__nav .f-button.is-prev,.is-vertical .fancybox__nav .f-button.is-prev{top:var(--f-button-next-pos)}.is-vertical .f-carousel__nav .f-button.is-next,.is-vertical .fancybox__nav .f-button.is-next{bottom:var(--f-button-next-pos)}.is-vertical .f-carousel__nav .f-button.is-prev svg,.is-vertical .f-carousel__nav .f-button.is-next svg,.is-vertical .fancybox__nav .f-button.is-prev svg,.is-vertical .fancybox__nav .f-button.is-next svg{transform:rotate(90deg)}.f-carousel__nav .f-button:disabled,.fancybox__nav .f-button:disabled{pointer-events:none}html.with-fancybox{width:auto;overflow:visible;scroll-behavior:auto}html.with-fancybox body{touch-action:none}html.with-fancybox body.hide-scrollbar{width:auto;margin-right:calc(var(--fancybox-body-margin, 0px) + var(--fancybox-scrollbar-compensate, 0px));overflow:hidden!important;overscroll-behavior-y:none}.fancybox__container{--fancybox-color: #dbdbdb;--fancybox-hover-color: #fff;--fancybox-bg: rgba(24, 24, 27, .98);--fancybox-slide-gap: 10px;--f-spinner-width: 50px;--f-spinner-height: 50px;--f-spinner-color-1: rgba(255, 255, 255, .1);--f-spinner-color-2: #bbb;--f-spinner-stroke: 3.65;position:fixed;top:0;left:0;bottom:0;right:0;direction:ltr;display:flex;flex-direction:column;box-sizing:border-box;margin:0;padding:0;color:#f8f8f8;-webkit-tap-highlight-color:rgba(0,0,0,0);overflow:visible;z-index:var(--fancybox-zIndex, 1050);outline:none;transform-origin:top left;-webkit-text-size-adjust:100%;-moz-text-size-adjust:none;-ms-text-size-adjust:100%;text-size-adjust:100%;overscroll-behavior-y:contain}.fancybox__container *,.fancybox__container *:before,.fancybox__container *:after{box-sizing:inherit}.fancybox__container::backdrop{background-color:#0000}.fancybox__backdrop{position:fixed;top:0;left:0;bottom:0;right:0;z-index:-1;background:var(--fancybox-bg);opacity:var(--fancybox-opacity, 1);will-change:opacity}.fancybox__carousel{position:relative;box-sizing:border-box;flex:1;min-height:0;z-index:10;overflow-y:visible;overflow-x:clip}.fancybox__viewport{width:100%;height:100%}.fancybox__viewport.is-draggable{cursor:move;cursor:grab}.fancybox__viewport.is-dragging{cursor:move;cursor:grabbing}.fancybox__track{display:flex;margin:0 auto;height:100%}.fancybox__slide{flex:0 0 auto;position:relative;display:flex;flex-direction:column;align-items:center;width:100%;height:100%;margin:0 var(--fancybox-slide-gap) 0 0;padding:4px;overflow:auto;overscroll-behavior:contain;transform:translateZ(0);backface-visibility:hidden}.fancybox__container:not(.is-compact) .fancybox__slide.has-close-btn{padding-top:40px}.fancybox__slide.has-iframe,.fancybox__slide.has-video,.fancybox__slide.has-html5video,.fancybox__slide.has-image{overflow:hidden}.fancybox__slide.has-image.is-animating,.fancybox__slide.has-image.is-selected{overflow:visible}.fancybox__slide:before,.fancybox__slide:after{content:"";flex:0 0 0;margin:auto}.fancybox__backdrop:empty,.fancybox__viewport:empty,.fancybox__track:empty,.fancybox__slide:empty{display:block}.fancybox__content{align-self:center;display:flex;flex-direction:column;position:relative;margin:0;padding:2rem;max-width:100%;color:var(--fancybox-content-color, #374151);background:var(--fancybox-content-bg, #fff);cursor:default;border-radius:0;z-index:20}.is-loading .fancybox__content{opacity:0}.is-draggable .fancybox__content{cursor:move;cursor:grab}.can-zoom_in .fancybox__content{cursor:zoom-in}.can-zoom_out .fancybox__content{cursor:zoom-out}.is-dragging .fancybox__content{cursor:move;cursor:grabbing}.fancybox__content [data-selectable],.fancybox__content [contenteditable]{cursor:auto}.fancybox__slide.has-image>.fancybox__content{padding:0;background:#0000;min-height:1px;background-repeat:no-repeat;background-size:contain;background-position:center center;transition:none;transform:translateZ(0);backface-visibility:hidden}.fancybox__slide.has-image>.fancybox__content>picture>img{width:100%;height:auto;max-height:100%}.is-animating .fancybox__content,.is-dragging .fancybox__content{will-change:transform,width,height}.fancybox-image{margin:auto;display:block;width:100%;height:100%;min-height:0;object-fit:contain;-webkit-user-select:none;user-select:none;filter:blur(0px)}.fancybox__caption{align-self:center;max-width:100%;flex-shrink:0;margin:0;padding:14px 0 4px;overflow-wrap:anywhere;line-height:1.375;color:var(--fancybox-color, currentColor);opacity:var(--fancybox-opacity, 1);cursor:auto;visibility:visible}.is-loading .fancybox__caption,.is-closing .fancybox__caption{opacity:0;visibility:hidden}.is-compact .fancybox__caption{padding-bottom:0}.f-button.is-close-btn{--f-button-svg-stroke-width: 2;position:absolute;top:0;right:8px;z-index:40}.fancybox__content>.f-button.is-close-btn{--f-button-width: 34px;--f-button-height: 34px;--f-button-border-radius: 4px;--f-button-color: var(--fancybox-color, #fff);--f-button-hover-color: var(--fancybox-color, #fff);--f-button-bg: transparent;--f-button-hover-bg: transparent;--f-button-active-bg: transparent;--f-button-svg-width: 22px;--f-button-svg-height: 22px;position:absolute;top:-38px;right:0;opacity:.75}.is-loading .fancybox__content>.f-button.is-close-btn{visibility:hidden}.is-zooming-out .fancybox__content>.f-button.is-close-btn{visibility:hidden}.fancybox__content>.f-button.is-close-btn:hover{opacity:1}.fancybox__footer{padding:0;margin:0;position:relative}.fancybox__footer .fancybox__caption{width:100%;padding:24px;opacity:var(--fancybox-opacity, 1);transition:all .25s ease}.is-compact .fancybox__footer{position:absolute;bottom:0;left:0;right:0;z-index:20;background:#18181b80}.is-compact .fancybox__footer .fancybox__caption{padding:12px}.is-compact .fancybox__content>.f-button.is-close-btn{--f-button-border-radius: 50%;--f-button-color: #fff;--f-button-hover-color: #fff;--f-button-outline-color: #000;--f-button-bg: rgba(0, 0, 0, .6);--f-button-active-bg: rgba(0, 0, 0, .6);--f-button-hover-bg: rgba(0, 0, 0, .6);--f-button-svg-width: 18px;--f-button-svg-height: 18px;--f-button-svg-filter: none;top:5px;right:5px}.fancybox__nav{--f-button-width: 50px;--f-button-height: 50px;--f-button-border: 0;--f-button-border-radius: 50%;--f-button-color: var(--fancybox-color);--f-button-hover-color: var(--fancybox-hover-color);--f-button-bg: transparent;--f-button-hover-bg: rgba(24, 24, 27, .3);--f-button-active-bg: rgba(24, 24, 27, .5);--f-button-shadow: none;--f-button-transition: all .15s ease;--f-button-transform: none;--f-button-svg-width: 26px;--f-button-svg-height: 26px;--f-button-svg-stroke-width: 2.5;--f-button-svg-fill: none;--f-button-svg-filter: drop-shadow(1px 1px 1px rgba(24, 24, 27, .5));--f-button-svg-disabled-opacity: .65;--f-button-next-pos: 1rem;--f-button-prev-pos: 1rem;opacity:var(--fancybox-opacity, 1)}.fancybox__nav .f-button:before{position:absolute;content:"";top:-30px;right:-20px;left:-20px;bottom:-30px;z-index:1}.is-idle .fancybox__nav{animation:.15s ease-out both f-fadeOut}.is-idle.is-compact .fancybox__footer{pointer-events:none;animation:.15s ease-out both f-fadeOut}.fancybox__slide>.f-spinner{position:absolute;top:50%;left:50%;margin:var(--f-spinner-top, calc(var(--f-spinner-width) * -.5)) 0 0 var(--f-spinner-left, calc(var(--f-spinner-height) * -.5));z-index:30;cursor:pointer}.fancybox-protected{position:absolute;top:0;left:0;right:0;bottom:0;z-index:40;-webkit-user-select:none;user-select:none}.fancybox-ghost{position:absolute;top:0;left:0;width:100%;height:100%;min-height:0;object-fit:contain;z-index:40;-webkit-user-select:none;user-select:none;pointer-events:none}.fancybox-focus-guard{outline:none;opacity:0;position:fixed;pointer-events:none}.fancybox__container:not([aria-hidden]){opacity:0}.fancybox__container.is-animated[aria-hidden=false]>*:not(.fancybox__backdrop,.fancybox__carousel),.fancybox__container.is-animated[aria-hidden=false] .fancybox__carousel>*:not(.fancybox__viewport),.fancybox__container.is-animated[aria-hidden=false] .fancybox__slide>*:not(.fancybox__content){animation:var(--f-interface-enter-duration, .25s) ease .1s backwards f-fadeIn}.fancybox__container.is-animated[aria-hidden=false] .fancybox__backdrop{animation:var(--f-backdrop-enter-duration, .35s) ease backwards f-fadeIn}.fancybox__container.is-animated[aria-hidden=true]>*:not(.fancybox__backdrop,.fancybox__carousel),.fancybox__container.is-animated[aria-hidden=true] .fancybox__carousel>*:not(.fancybox__viewport),.fancybox__container.is-animated[aria-hidden=true] .fancybox__slide>*:not(.fancybox__content){animation:var(--f-interface-exit-duration, .15s) ease forwards f-fadeOut}.fancybox__container.is-animated[aria-hidden=true] .fancybox__backdrop{animation:var(--f-backdrop-exit-duration, .35s) ease forwards f-fadeOut}.has-iframe .fancybox__content,.has-map .fancybox__content,.has-pdf .fancybox__content,.has-youtube .fancybox__content,.has-vimeo .fancybox__content,.has-html5video .fancybox__content{max-width:100%;flex-shrink:1;min-height:1px;overflow:visible}.has-iframe .fancybox__content,.has-map .fancybox__content,.has-pdf .fancybox__content{width:calc(100% - 120px);height:90%}.fancybox__container.is-compact .has-iframe .fancybox__content,.fancybox__container.is-compact .has-map .fancybox__content,.fancybox__container.is-compact .has-pdf .fancybox__content{width:100%;height:100%}.has-youtube .fancybox__content,.has-vimeo .fancybox__content,.has-html5video .fancybox__content{width:960px;height:540px;max-width:100%;max-height:100%}.has-map .fancybox__content,.has-pdf .fancybox__content,.has-youtube .fancybox__content,.has-vimeo .fancybox__content,.has-html5video .fancybox__content{padding:0;background:#18181be6;color:#fff}.has-map .fancybox__content{background:#e5e3df}.fancybox__html5video,.fancybox__iframe{border:0;display:block;height:100%;width:100%;background:#0000}.fancybox-placeholder{border:0!important;clip:rect(1px,1px,1px,1px)!important;-webkit-clip-path:inset(50%)!important;clip-path:inset(50%)!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;white-space:nowrap!important}.f-carousel__thumbs{--f-thumb-width: 96px;--f-thumb-height: 72px;--f-thumb-outline: 0;--f-thumb-outline-color: #5eb0ef;--f-thumb-opacity: 1;--f-thumb-hover-opacity: 1;--f-thumb-selected-opacity: 1;--f-thumb-border-radius: 2px;--f-thumb-offset: 0px;--f-button-next-pos: 0;--f-button-prev-pos: 0}.f-carousel__thumbs.is-classic{--f-thumb-gap: 8px;--f-thumb-opacity: .5;--f-thumb-hover-opacity: 1;--f-thumb-selected-opacity: 1}.f-carousel__thumbs.is-modern{--f-thumb-gap: 4px;--f-thumb-extra-gap: 16px;--f-thumb-clip-width: 46px}.f-thumbs{position:relative;flex:0 0 auto;margin:0;overflow:hidden;-webkit-tap-highlight-color:rgba(0,0,0,0);-webkit-user-select:none;user-select:none;perspective:1000px;transform:translateZ(0)}.f-thumbs .f-spinner{position:absolute;top:0;left:0;width:100%;height:100%;border-radius:2px;background-image:linear-gradient(#ebeff2,#e2e8f0);z-index:-1}.f-thumbs .f-spinner svg{display:none}.f-thumbs.is-vertical{height:100%}.f-thumbs__viewport{width:100%;height:auto;overflow:hidden;transform:translateZ(0)}.f-thumbs__track{display:flex}.f-thumbs__slide{position:relative;flex:0 0 auto;box-sizing:content-box;display:flex;align-items:center;justify-content:center;padding:0;margin:0;width:var(--f-thumb-width);height:var(--f-thumb-height);overflow:visible;cursor:pointer}.f-thumbs__slide.is-loading img{opacity:0}.is-classic .f-thumbs__viewport{height:100%}.is-modern .f-thumbs__track{width:max-content}.is-modern .f-thumbs__track:before{content:"";position:absolute;top:0;bottom:0;left:calc((var(--f-thumb-clip-width, 0))*-.5);width:calc(var(--width, 0)*1px + var(--f-thumb-clip-width, 0));cursor:pointer}.is-modern .f-thumbs__slide{width:var(--f-thumb-clip-width);transform:translate3d(calc(var(--shift, 0) * -1px),0,0);transition:none;pointer-events:none}.is-modern.is-resting .f-thumbs__slide{transition:transform .33s ease}.is-modern.is-resting .f-thumbs__slide__button{transition:clip-path .33s ease}.is-using-tab .is-modern .f-thumbs__slide:focus-within{filter:drop-shadow(-1px 0px 0px var(--f-thumb-outline-color)) drop-shadow(2px 0px 0px var(--f-thumb-outline-color)) drop-shadow(0px -1px 0px var(--f-thumb-outline-color)) drop-shadow(0px 2px 0px var(--f-thumb-outline-color))}.f-thumbs__slide__button{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:var(--f-thumb-width);height:100%;margin:0 -100%;padding:0;border:0;position:relative;border-radius:var(--f-thumb-border-radius);overflow:hidden;background:#0000;outline:none;cursor:pointer;pointer-events:auto;touch-action:manipulation;opacity:var(--f-thumb-opacity);transition:opacity .2s ease}.f-thumbs__slide__button:hover{opacity:var(--f-thumb-hover-opacity)}.f-thumbs__slide__button:focus:not(:focus-visible){outline:none}.f-thumbs__slide__button:focus-visible{outline:none;opacity:var(--f-thumb-selected-opacity)}.is-modern .f-thumbs__slide__button{--clip-path: inset( 0 calc( ((var(--f-thumb-width, 0) - var(--f-thumb-clip-width, 0))) * (1 - var(--progress, 0)) * .5 ) round var(--f-thumb-border-radius, 0) );clip-path:var(--clip-path)}.is-classic .is-nav-selected .f-thumbs__slide__button{opacity:var(--f-thumb-selected-opacity)}.is-classic .is-nav-selected .f-thumbs__slide__button:after{content:"";position:absolute;top:0;left:0;right:0;height:auto;bottom:0;border:var(--f-thumb-outline, 0) solid var(--f-thumb-outline-color, transparent);border-radius:var(--f-thumb-border-radius);animation:f-fadeIn .2s ease-out;z-index:10}.f-thumbs__slide__img{overflow:hidden;position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;margin:0;padding:var(--f-thumb-offset);box-sizing:border-box;pointer-events:none;object-fit:cover;border-radius:var(--f-thumb-border-radius)}.f-thumbs.is-horizontal .f-thumbs__track{padding:8px 0 12px}.f-thumbs.is-horizontal .f-thumbs__slide{margin:0 var(--f-thumb-gap) 0 0}.f-thumbs.is-vertical .f-thumbs__track{flex-wrap:wrap;padding:0 8px}.f-thumbs.is-vertical .f-thumbs__slide{margin:0 0 var(--f-thumb-gap) 0}.fancybox__thumbs{--f-thumb-width: 96px;--f-thumb-height: 72px;--f-thumb-border-radius: 2px;--f-thumb-outline: 2px;--f-thumb-outline-color: #ededed;position:relative;opacity:var(--fancybox-opacity, 1);transition:max-height .35s cubic-bezier(.23,1,.32,1)}.fancybox__thumbs.is-classic{--f-thumb-gap: 8px;--f-thumb-opacity: .5;--f-thumb-hover-opacity: 1}.fancybox__thumbs.is-classic .f-spinner{background-image:linear-gradient(#ffffff1a,#ffffff0d)}.fancybox__thumbs.is-modern{--f-thumb-gap: 4px;--f-thumb-extra-gap: 16px;--f-thumb-clip-width: 46px;--f-thumb-opacity: 1;--f-thumb-hover-opacity: 1}.fancybox__thumbs.is-modern .f-spinner{background-image:linear-gradient(#ffffff1a,#ffffff0d)}.fancybox__thumbs.is-horizontal{padding:0 var(--f-thumb-gap)}.fancybox__thumbs.is-vertical{padding:var(--f-thumb-gap) 0}.is-compact .fancybox__thumbs{--f-thumb-width: 64px;--f-thumb-clip-width: 32px;--f-thumb-height: 48px;--f-thumb-extra-gap: 10px}.fancybox__thumbs.is-masked{max-height:0px!important}.is-closing .fancybox__thumbs{transition:none!important}.fancybox__toolbar{--f-progress-color: var(--fancybox-color, rgba(255, 255, 255, .94));--f-button-width: 46px;--f-button-height: 46px;--f-button-color: var(--fancybox-color);--f-button-hover-color: var(--fancybox-hover-color);--f-button-bg: rgba(24, 24, 27, .65);--f-button-hover-bg: rgba(70, 70, 73, .65);--f-button-active-bg: rgba(90, 90, 93, .65);--f-button-border-radius: 0;--f-button-svg-width: 24px;--f-button-svg-height: 24px;--f-button-svg-stroke-width: 1.5;--f-button-svg-filter: drop-shadow(1px 1px 1px rgba(24, 24, 27, .15));--f-button-svg-fill: none;--f-button-svg-disabled-opacity: .65;display:flex;flex-direction:row;justify-content:space-between;margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI Adjusted,Segoe UI,Liberation Sans,sans-serif;color:var(--fancybox-color, currentColor);opacity:var(--fancybox-opacity, 1);text-shadow:var(--fancybox-toolbar-text-shadow, 1px 1px 1px rgba(0, 0, 0, .5));pointer-events:none;z-index:20}.fancybox__toolbar :focus-visible{z-index:1}.fancybox__toolbar.is-absolute,.is-compact .fancybox__toolbar{position:absolute;top:0;left:0;right:0}.is-idle .fancybox__toolbar{pointer-events:none;animation:.15s ease-out both f-fadeOut}.fancybox__toolbar__column{display:flex;flex-direction:row;flex-wrap:wrap;align-content:flex-start}.fancybox__toolbar__column.is-left,.fancybox__toolbar__column.is-right{flex-grow:1;flex-basis:0}.fancybox__toolbar__column.is-right{display:flex;justify-content:flex-end;flex-wrap:nowrap}.fancybox__infobar{padding:0 5px;line-height:var(--f-button-height);text-align:center;font-size:17px;font-variant-numeric:tabular-nums;-webkit-font-smoothing:subpixel-antialiased;cursor:default;-webkit-user-select:none;user-select:none}.fancybox__infobar span{padding:0 5px}.fancybox__infobar:not(:first-child):not(:last-child){background:var(--f-button-bg)}[data-fancybox-toggle-slideshow]{position:relative}[data-fancybox-toggle-slideshow] .f-progress{height:100%;opacity:.3}[data-fancybox-toggle-slideshow] svg g:first-child{display:flex}[data-fancybox-toggle-slideshow] svg g:last-child{display:none}.has-slideshow [data-fancybox-toggle-slideshow] svg g:first-child{display:none}.has-slideshow [data-fancybox-toggle-slideshow] svg g:last-child{display:flex}[data-fancybox-toggle-fullscreen] svg g:first-child{display:flex}[data-fancybox-toggle-fullscreen] svg g:last-child{display:none}:fullscreen [data-fancybox-toggle-fullscreen] svg g:first-child{display:none}:fullscreen [data-fancybox-toggle-fullscreen] svg g:last-child{display:flex}.f-progress{position:absolute;top:0;left:0;right:0;height:3px;transform:scaleX(0);transform-origin:0;transition-property:transform;transition-timing-function:linear;background:var(--f-progress-color, var(--f-carousel-theme-color, #0091ff));z-index:30;-webkit-user-select:none;user-select:none;pointer-events:none}.widget-images__item-desc span:first-child:after{content:"";width:2px;height:2px;border-radius:50%;display:flex;align-items:center;background:#676a6c;margin:0 5px}.disabled{cursor:not-allowed!important}.item__text-content,.item{transition:all .5s cubic-bezier(.4,0,.2,1)}.item:hover .item__text-content{opacity:.8}.vs-widget-images .vs-button{background-color:#2563eb;color:#fff;font-size:.875rem;line-height:1.25rem;font-weight:600}.border-top:not(:first-child){--tw-border-opacity: 1;border-color:#e5e7eb;border-top-width:1px}.widget-comment-form .vs-button{padding:.625rem 1rem;font-size:.75rem;line-height:1rem;font-weight:500}.widget-comment-form .vs-button:focus{border:transparent;--tw-ring-opacity: 1;--tw-ring-color: rgb(191 219 254);--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 rgba(0, 0, 0, 0))}.grid[data-v-86a4c28d]{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:1rem}.admin-wrapper[data-v-3a278cfb]{display:flex;height:100vh;align-items:start}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengis/admin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "This project Softpro Admin",
|
|
5
5
|
"main": "dist/admin.js",
|
|
6
6
|
"type": "module",
|
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
"build": "vite build",
|
|
20
20
|
"build-app": "cross-env APP=true vite build",
|
|
21
21
|
"admin": "cross-env NODE_ENV=admin npm run start",
|
|
22
|
+
"admin1": "cross-env NODE_ENV=admin1 npm run start",
|
|
22
23
|
"prod": "cross-env NODE_ENV=production npm run start",
|
|
23
24
|
"start": "node --watch-path=server server vite ",
|
|
24
|
-
"dev": "
|
|
25
|
+
"docs:dev": "vitepress dev docs",
|
|
26
|
+
"docs:build": "vitepress build docs",
|
|
27
|
+
"docs:preview": "vitepress preview docs"
|
|
25
28
|
},
|
|
26
29
|
"keywords": [],
|
|
27
30
|
"author": "Softpro",
|
|
@@ -29,24 +32,34 @@
|
|
|
29
32
|
"dependencies": {
|
|
30
33
|
"@opengis/fastify-auth": "^1.0.20",
|
|
31
34
|
"@opengis/fastify-file": "^1.0.17",
|
|
32
|
-
"@opengis/fastify-table": "^1.
|
|
33
|
-
"@opengis/v3-core": "^0.1.
|
|
35
|
+
"@opengis/fastify-table": "^1.1.4",
|
|
36
|
+
"@opengis/v3-core": "^0.1.92",
|
|
34
37
|
"@opengis/v3-filter": "^0.0.31",
|
|
38
|
+
"@turf/turf": "^7.1.0",
|
|
35
39
|
"@vitejs/plugin-vue": "^5.0.4",
|
|
36
40
|
"close-with-grace": "^1.3.0",
|
|
37
41
|
"cross-env": "^7.0.3",
|
|
38
42
|
"fastify": "^4.26.1",
|
|
39
43
|
"fastify-plugin": "^4.0.0",
|
|
44
|
+
"maplibre-gl": "^4.7.0",
|
|
40
45
|
"moment": "^2.30.1",
|
|
41
46
|
"vite": "^5.1.4",
|
|
42
47
|
"vue": "^3.4.21",
|
|
43
48
|
"vue-router": "^4.3.0"
|
|
44
49
|
},
|
|
45
50
|
"devDependencies": {
|
|
51
|
+
"@panzoom/panzoom": "^4.5.1",
|
|
46
52
|
"@vue/eslint-config-typescript": "^12.0.0",
|
|
47
53
|
"eslint": "^8.49.0",
|
|
48
54
|
"eslint-config-airbnb": "^19.0.4",
|
|
49
55
|
"eslint-plugin-import": "^2.25.3",
|
|
50
|
-
"eslint-plugin-vue": "^9.17.0"
|
|
56
|
+
"eslint-plugin-vue": "^9.17.0",
|
|
57
|
+
"markdown-it-abbr": "^2.0.0",
|
|
58
|
+
"mermaid": "^10.9.0",
|
|
59
|
+
"sass-embedded": "^1.79.1",
|
|
60
|
+
"vitepress": "^1.1.3",
|
|
61
|
+
"vitepress-plugin-mermaid": "^2.0.16",
|
|
62
|
+
"vitepress-plugin-tabs": "^0.5.0",
|
|
63
|
+
"vitepress-sidebar": "^1.22.0"
|
|
51
64
|
}
|
|
52
65
|
}
|
package/plugin.js
CHANGED
package/server/plugins/vite.js
CHANGED
|
@@ -11,14 +11,19 @@ async function plugin(fastify) {
|
|
|
11
11
|
// vite server
|
|
12
12
|
if (!isProduction) {
|
|
13
13
|
const vite = await import('vite');
|
|
14
|
-
const viteDevMiddleware = (
|
|
15
|
-
await vite.createServer({
|
|
16
|
-
server: {
|
|
17
|
-
middlewareMode: true,
|
|
18
|
-
},
|
|
19
|
-
})
|
|
20
|
-
).middlewares;
|
|
21
14
|
|
|
15
|
+
const viteServer = await vite.createServer({
|
|
16
|
+
server: {
|
|
17
|
+
middlewareMode: true,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
// hot reload
|
|
21
|
+
viteServer.watcher.on('all', function (d, t) {
|
|
22
|
+
if (!t.includes('module')) return;
|
|
23
|
+
console.log(d, t);
|
|
24
|
+
viteServer.ws.send({type: 'full-reload' });
|
|
25
|
+
});
|
|
26
|
+
|
|
22
27
|
// this is middleware for vite's dev servert
|
|
23
28
|
fastify.addHook('onRequest', async (req, reply) => {
|
|
24
29
|
const { user } = req.session?.passport || {};
|
|
@@ -28,7 +33,7 @@ async function plugin(fastify) {
|
|
|
28
33
|
}
|
|
29
34
|
|
|
30
35
|
const next = () => new Promise((resolve) => {
|
|
31
|
-
|
|
36
|
+
viteServer.middlewares(req.raw, reply.raw, () => resolve());
|
|
32
37
|
});
|
|
33
38
|
await next();
|
|
34
39
|
});
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { getTemplate } from "@opengis/fastify-table/utils.js";
|
|
2
|
+
// import pgClients from '@opengis/fastify-table/pg/funcs/pgClients.js';
|
|
3
|
+
|
|
4
|
+
import getTableSql from './util/getTableSql.js';
|
|
5
|
+
import getFilterQuery from './util/getFilterQuery.js';
|
|
6
|
+
import getOptimizedQuery from './util/getOptimizedQuery.js';
|
|
7
|
+
|
|
8
|
+
async function getFilterSQL({
|
|
9
|
+
pg: pg1, funcs, table, filter, search, filterList, query,
|
|
10
|
+
}) {
|
|
11
|
+
if (!table) return { error: 'param table is required', status: 400 };
|
|
12
|
+
|
|
13
|
+
const pg = pg1 || funcs.getPG();
|
|
14
|
+
const body = await getTemplate('table', table);
|
|
15
|
+
|
|
16
|
+
const sqlList = body?.sql?.length
|
|
17
|
+
? body?.sql?.filter((el) => !el.disabled && el?.sql?.replace)
|
|
18
|
+
.map((el) => ` left join lateral (${el.filter ? el.sql.replace(/limit 1/ig, '') : el.sql}) as ${el.name} on 1=1 `).join(' ')
|
|
19
|
+
: '';
|
|
20
|
+
const fieldQuery = `select * from ${body?.table || table} ${sqlList ? ` t ${sqlList}` : ''} where 1=1 limit 0`;
|
|
21
|
+
const { fields = [] } = await pg.query(fieldQuery);
|
|
22
|
+
|
|
23
|
+
const { fields: fieldsModel } = pg.pk[body?.table] ? await pg.query(`select * from ${body.table} limit 0`) : {};
|
|
24
|
+
|
|
25
|
+
const autoSearchColumn = fields?.filter((el) => pg.pgType?.[el.dataTypeID] === 'text')?.map((el) => el.name).join(',');
|
|
26
|
+
const searchColumn = body?.search_column || autoSearchColumn;
|
|
27
|
+
const fieldsList = (fieldsModel || fields)?.map((el) => el.name);
|
|
28
|
+
try {
|
|
29
|
+
const tableSQL = await getTableSql({
|
|
30
|
+
pg, body, table, fields,
|
|
31
|
+
});
|
|
32
|
+
const sval = `ilike '%${decodeURIComponent(search).replace(/'/g, "''")}%'`;
|
|
33
|
+
const searchQuery = search && searchColumn
|
|
34
|
+
? ` (${searchColumn.split(',')?.map((name) => {
|
|
35
|
+
const { pk } = tableSQL.find((el) => el.name === name) || {};
|
|
36
|
+
return pk && !fieldsList.includes(name) ? `${pk} in (select ${pk} from (${fieldQuery})q where ${name} ${sval})` : `${name} ${sval}`;
|
|
37
|
+
}).join(' or ')} )` : '';
|
|
38
|
+
|
|
39
|
+
const filterList1 = await Promise.all((filterList || (body?.filter_list || []).concat(body?.filterInline || []).concat(body?.filterCustom || []).concat(body?.filterState || []).concat(body?.filterList || []))
|
|
40
|
+
?.map(async (el) => {
|
|
41
|
+
if (!el?.data) return el;
|
|
42
|
+
const cls = await getTemplate(['cls', 'select'], el.data);
|
|
43
|
+
if (Array.isArray(cls) && cls?.length) {
|
|
44
|
+
Object.assign(el, { options: cls });
|
|
45
|
+
} else if (typeof cls === 'string') {
|
|
46
|
+
Object.assign(el, { sql: cls });
|
|
47
|
+
}
|
|
48
|
+
return el;
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
const filters = getFilterQuery({
|
|
52
|
+
pg,
|
|
53
|
+
filter,
|
|
54
|
+
tableSQL,
|
|
55
|
+
fields,
|
|
56
|
+
filterList: filterList1,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// filter
|
|
60
|
+
const filterQuery = filters?.filter((el) => el.query)?.map((el) => `${el.query} `).join(' and ');
|
|
61
|
+
const q = [body?.query, query, searchQuery, filterQuery].filter((el) => el).join(' and ');
|
|
62
|
+
|
|
63
|
+
// table
|
|
64
|
+
const modelQuery = body?.model || body?.table || table;
|
|
65
|
+
const optimizedSQL = `select * from ${getOptimizedQuery({ body, table, q })} `;
|
|
66
|
+
const tableCount = getOptimizedQuery({ body, table, q }, true);
|
|
67
|
+
// console.log(optimizedSQL);
|
|
68
|
+
return {
|
|
69
|
+
filterList,
|
|
70
|
+
q,
|
|
71
|
+
optimizedSQL,
|
|
72
|
+
tableCount,
|
|
73
|
+
table: modelQuery,
|
|
74
|
+
searchQuery,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
throw new Error(err.toString());
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export default getFilterSQL;
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
const dateTypeList = ['date', 'timestamp', 'timestamp without time zone'];
|
|
2
|
+
const numberTypeList = ['float8', 'int4', 'int8', 'numeric', 'double precision', 'integer'];
|
|
3
|
+
|
|
4
|
+
function dt(y, m, d) {
|
|
5
|
+
return new Date(Date.UTC(y, m, d)).toISOString().slice(0, 10);
|
|
6
|
+
}
|
|
7
|
+
const dp = {
|
|
8
|
+
d: new Date().getDate(),
|
|
9
|
+
w: new Date().getDate() - (new Date().getDay() || 7) + 1,
|
|
10
|
+
m: new Date().getMonth(),
|
|
11
|
+
q: (new Date().getMonth() / 4).toFixed() * 3,
|
|
12
|
+
y: new Date().getFullYear(),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
function formatDateISOString(date) {
|
|
16
|
+
if (!date?.includes('.')) return date;
|
|
17
|
+
const [day, month, year] = date.split('.');
|
|
18
|
+
return `${year}-${month}-${day}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function formatValue({
|
|
22
|
+
filterType, filter, name, value, operator = '=', fieldType = 'text', uid = 1, optimize,
|
|
23
|
+
}) {
|
|
24
|
+
if (!name || !value) return {};
|
|
25
|
+
|
|
26
|
+
// current day, week, month, year etc.
|
|
27
|
+
if (dateTypeList.includes(fieldType) && !value?.includes('_') && ['cd', 'cw', 'cm', 'cq', 'cy'].includes(value)) {
|
|
28
|
+
const query = {
|
|
29
|
+
cd: `${name}::date = '${dt(dp.y, dp.m, dp.d)}'::date`,
|
|
30
|
+
cw: `${name}::date >= '${dt(dp.y, dp.m, dp.w)}'::date and ${name} <= '${dt(dp.y, dp.m, dp.w + 6)}'::date`,
|
|
31
|
+
cm: `${name}::date >= '${dt(dp.y, dp.m, 1)}'::date and ${name} <= '${dt(dp.y, dp.m + 1, 0)}'::date`,
|
|
32
|
+
cq: `${name}::date >= '${dt(dp.y, dp.q, 1)}'::date and ${name} <= '${dt(dp.y, dp.q + 3, 0)}'::date`,
|
|
33
|
+
cy: `${name}::date >= '${dt(dp.y, 0, 1)}'::date and ${name}::date <= '${dt(dp.y, 11, 31)}'::date`,
|
|
34
|
+
}[value];
|
|
35
|
+
return { op: '=', query };
|
|
36
|
+
}
|
|
37
|
+
// date range
|
|
38
|
+
if (dateTypeList.includes(fieldType) && value?.includes('_')) {
|
|
39
|
+
const [min, max] = value.split('_');
|
|
40
|
+
const query = `${name} >= '${min}'::date and ${name} <= '${max}'::date`;
|
|
41
|
+
return { op: 'between', query };
|
|
42
|
+
}
|
|
43
|
+
// v3 filter date range, example - "01.01.2024-31.12.2024"
|
|
44
|
+
if (dateTypeList.includes(fieldType) && value?.includes('.') && value?.indexOf('-') === 10 && value?.length === 21) {
|
|
45
|
+
const [startDate, endDate] = value.split('-');
|
|
46
|
+
const min = formatDateISOString(startDate);
|
|
47
|
+
const max = formatDateISOString(endDate);
|
|
48
|
+
const query = `${name}::date >= '${min}'::date and ${name}::date <= '${max}'::date`;
|
|
49
|
+
return { op: 'between', query };
|
|
50
|
+
}
|
|
51
|
+
// my rows
|
|
52
|
+
if (value === 'me' && uid && fieldType === 'text') {
|
|
53
|
+
return { op: '=', query: `${name}::text = '${uid}'` };
|
|
54
|
+
}
|
|
55
|
+
const formatType = {
|
|
56
|
+
float8: 'numeric',
|
|
57
|
+
int4: 'numeric',
|
|
58
|
+
int8: 'numeric',
|
|
59
|
+
varchar: 'text',
|
|
60
|
+
bool: 'boolean',
|
|
61
|
+
geometry: 'geom',
|
|
62
|
+
}[fieldType] || 'text';
|
|
63
|
+
|
|
64
|
+
if (optimize && optimize.name !== optimize.pk) {
|
|
65
|
+
const val = filterType === 'text' ? `ilike '%${value}%'` : `= any('{${value}}')`;
|
|
66
|
+
return {
|
|
67
|
+
op: '~',
|
|
68
|
+
query: fieldType?.includes('[]')
|
|
69
|
+
? `${optimize.pk} && (select array_agg(${optimize.pk}) from ${optimize.table} where ${name} ${val} )`
|
|
70
|
+
: `${optimize.pk} in (select ${optimize.pk} from ${optimize.table} where ${name} ${val} )`,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (filter.sql && false) {
|
|
75
|
+
return { op: '~', query: filter.sql.replace('{val}', value) };
|
|
76
|
+
}
|
|
77
|
+
if (fieldType?.includes('[]')) {
|
|
78
|
+
return { op: 'in', query: `'{${value}}'::text[] && ${name}::text[]` };
|
|
79
|
+
}
|
|
80
|
+
// multiple items of 1 param
|
|
81
|
+
if (value?.indexOf(',') !== -1) {
|
|
82
|
+
const values = value.split(',').filter((el) => el !== 'null');
|
|
83
|
+
const query = value?.indexOf('null' !== -1)
|
|
84
|
+
? `( ${name} is null or ${name}::text in (${values?.map((el) => `'${el}'`).join(',')}) )`
|
|
85
|
+
: `${name}::text in (${value.split(',')?.map((el) => `'${el}'`).join(',')})`;
|
|
86
|
+
return { op: 'in', query };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// v3 filter number range, example - "100_500"
|
|
90
|
+
if (numberTypeList.includes(fieldType) && value?.indexOf('_') !== -1) {
|
|
91
|
+
const [min, max] = value.split('_');
|
|
92
|
+
const query = (max === 'max' ? `${name} > ${min}` : null) || (min === 'min' ? `${name} < ${max}` : null) || `${name} between ${min} and ${max}`;
|
|
93
|
+
return { op: 'between', query };
|
|
94
|
+
}
|
|
95
|
+
// number range
|
|
96
|
+
if (numberTypeList.includes(fieldType) && value?.indexOf('-') !== -1) {
|
|
97
|
+
const [min, max] = value.split('-');
|
|
98
|
+
if (min === 'min' && max === 'max') return {};
|
|
99
|
+
const query = (max === 'max' ? `${name} > ${min}` : null) || (min === 'min' ? `${name} < ${max}` : null) || `${name} between ${min} and ${max}`;
|
|
100
|
+
return { op: 'between', query };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (['<', '>'].includes(operator)) {
|
|
104
|
+
const query = `${name} ${operator} '${value}'::${formatType}`;
|
|
105
|
+
return { op: operator, query };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (operator === '=' && filterType !== 'text') {
|
|
109
|
+
const query = {
|
|
110
|
+
null: `${name} is null`,
|
|
111
|
+
notnull: `${name} is not null`,
|
|
112
|
+
}[value] || `${name}::${formatType}='${value}'::${formatType}`;
|
|
113
|
+
return { op: '=', query };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (['~', '='].includes(operator)) {
|
|
117
|
+
const query = filter?.data && filter?.sql
|
|
118
|
+
? `${filter?.name} in ( ( with q(id,name) as (${filter?.sql}) select id from q where name ilike '%${value}%') )` // filter with cls
|
|
119
|
+
: `${name}::text ilike '%${value}%'`; // simple filter
|
|
120
|
+
return { op: 'ilike', query };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// json
|
|
124
|
+
if (name.includes('.')) {
|
|
125
|
+
const [col, prop] = name.split('.');
|
|
126
|
+
const query = ` ${col}->>'${prop}' in ('${value.join("','")}')`;
|
|
127
|
+
return { op: 'in', query };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// geometry
|
|
131
|
+
if (['geometry'].includes(fieldType)) {
|
|
132
|
+
const bbox = value[0].split('_');
|
|
133
|
+
|
|
134
|
+
if (bbox?.length === 4) {
|
|
135
|
+
const query = ` ${name} && 'box(${bbox[0]} ${bbox[1]},${bbox[2]} ${bbox[3]})'::box2d `;
|
|
136
|
+
return { op: '&&', query };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return {};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export default formatValue;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
async function getCustomQuery({
|
|
2
|
+
pg, table, customFilter,
|
|
3
|
+
}) {
|
|
4
|
+
if (!customFilter) return null;
|
|
5
|
+
const customFilterList = customFilter?.split(',')?.map((el) => el?.split('_').pop());
|
|
6
|
+
const { property_json: customFilterSQL } = await pg.one(`select json_agg(json_build_object('id',property_id,'name',property_key,'query',property_text)
|
|
7
|
+
) as property_json from admin.properties where property_key is not null and property_entity='customQuery' and object_id=$1`, [table]);
|
|
8
|
+
const data = customFilterSQL?.length ? customFilterSQL.filter((el) => customFilterList.includes(el.id)) || [] : [];
|
|
9
|
+
const customQuery = data?.map((el) => el.query).join(' and ');
|
|
10
|
+
return `${customQuery}`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default getCustomQuery;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* eslint-disable no-continue */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {Number} opt.json - (1|0) 1 - Результат - Object, 0 - String
|
|
5
|
+
* @param {String} opt.query - запит до таблиці
|
|
6
|
+
* @param {String} opt.hash - інформація з хешу по запиту
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import formatValue from './formatValue.js';
|
|
10
|
+
|
|
11
|
+
function getQuery({
|
|
12
|
+
pg, filter: filterStr, tableSQL, fields, filterList,
|
|
13
|
+
}) {
|
|
14
|
+
if (!filterStr) return null; // filter list API
|
|
15
|
+
|
|
16
|
+
const mainOperators = ['=', '~', '>', '<'];
|
|
17
|
+
|
|
18
|
+
const filterQueryArray = decodeURI(filterStr?.replace(/(^,)|(,$)/g, '')).replace(/'/g, '').split(/[;|]/);
|
|
19
|
+
|
|
20
|
+
const resultList = [];
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < filterQueryArray.length; i += 1) {
|
|
23
|
+
const item = filterQueryArray[i];
|
|
24
|
+
const operator = mainOperators?.find((el) => item.indexOf(el) !== -1) || '=';
|
|
25
|
+
const [name] = item.split(operator);
|
|
26
|
+
|
|
27
|
+
// skip already added filter
|
|
28
|
+
if (resultList.find((el) => el.name === name)) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// find all value
|
|
33
|
+
const value = filterQueryArray.filter((el) => el.startsWith(name)).map((el) => el.substring(name.length + 1)).join(',');
|
|
34
|
+
|
|
35
|
+
const optimize = fields?.find((el) => el.name === name) ? null : tableSQL.find((el) => el.name === name);
|
|
36
|
+
|
|
37
|
+
// find field and skip not exists
|
|
38
|
+
const { dataTypeID } = fields?.find((el) => el.name === name) || fields?.find((el) => el.name === optimize?.pk) || {};
|
|
39
|
+
if (!dataTypeID) continue;
|
|
40
|
+
|
|
41
|
+
const type = pg.pgType?.[dataTypeID];
|
|
42
|
+
|
|
43
|
+
// filter
|
|
44
|
+
const filter = filterList?.find((el) => [el.id, el.name].includes(name)) || { type: 'text' };
|
|
45
|
+
const filterType = filter.type?.toLowerCase();
|
|
46
|
+
|
|
47
|
+
// format query
|
|
48
|
+
const { op, query } = formatValue({
|
|
49
|
+
filter,
|
|
50
|
+
optimize,
|
|
51
|
+
filterType,
|
|
52
|
+
name,
|
|
53
|
+
value: decodeURIComponent(value),
|
|
54
|
+
operator,
|
|
55
|
+
fieldType: type || 'text',
|
|
56
|
+
}) || {};
|
|
57
|
+
if (!query) continue;
|
|
58
|
+
|
|
59
|
+
resultList.push({
|
|
60
|
+
name, value, query, operator: op, filterType, type,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return resultList;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export default getQuery;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
function getOptimizedQuery({ body, table, q }, count) {
|
|
2
|
+
const order = body?.orderby || body?.order ? `order by ${body?.orderby || body?.order}` : '';
|
|
3
|
+
|
|
4
|
+
const tableName = body?.table || body?.model || table;
|
|
5
|
+
|
|
6
|
+
const sqlList = body?.sql?.filter((el) => !el.disabled && el?.sql?.replace && (count ? el.count !== false : true))
|
|
7
|
+
.map((el) => ` left join lateral (${el.filter ? el.sql.replace(/limit 1/ig, '') : el.sql}) as ${el.name} on 1=1 `).join(' ');
|
|
8
|
+
|
|
9
|
+
return `(select * from ${tableName} ${sqlList ? ` t ${sqlList}` : ''} where 1=1 and ${q?.replace('q.', 't.') || '1=1'} ${order})q`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default getOptimizedQuery;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function getTable(table) {
|
|
2
|
+
const result = table?.toLowerCase()?.replace(/[\n\r]+/g, ' ')?.split(' from ')?.filter((el) => /^[a-z0-9_]+\.[a-z0-9_]+/.test(el))
|
|
3
|
+
?.map((el) => el.split(/[ )]/)[0]);
|
|
4
|
+
return result;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {Number} opt.json - (1|0) 1 - Результат - Object, 0 - String
|
|
9
|
+
* @param {String} opt.query - запит до таблиці
|
|
10
|
+
* @param {String} opt.hash - інформація з хешу по запиту
|
|
11
|
+
*/
|
|
12
|
+
const tableSql = {};
|
|
13
|
+
async function getTableSql({
|
|
14
|
+
pg, body, table, fields,
|
|
15
|
+
}) {
|
|
16
|
+
if (tableSql[table]) return tableSql[table];
|
|
17
|
+
|
|
18
|
+
const fieldList = fields.map((el) => el.name);
|
|
19
|
+
|
|
20
|
+
const tableList = body?.sql?.map((el) => getTable(el.sql)).reduce((acc, el) => acc.concat(el), []).filter((el) => fieldList.includes(pg.pk[el]));
|
|
21
|
+
|
|
22
|
+
if (!tableList) { tableSql[table] = []; return []; }
|
|
23
|
+
|
|
24
|
+
const data = await Promise.all(tableList?.map(async (tableEl) => {
|
|
25
|
+
const { fields: fieldsEl } = await pg.query(`select * from ${tableEl} limit 0`);
|
|
26
|
+
return fieldsEl.map((el) => ({ name: el.name, table: tableEl, pk: pg.pk[tableEl] }));
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
tableSql[table] = data.reduce((acc, el) => acc.concat(el), []);
|
|
30
|
+
|
|
31
|
+
return tableSql[table];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export default getTableSql;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import getTemplate from "
|
|
1
|
+
import { getTemplate, metaFormat } from "@opengis/fastify-table/utils.js";
|
|
2
2
|
|
|
3
3
|
import getMeta from "@opengis/fastify-table/pg/funcs/getMeta.js";
|
|
4
4
|
import getAccess from "@opengis/fastify-table/crud/funcs/getAccess.js";
|
|
5
|
-
|
|
6
|
-
import getFilterSQL from "@opengis/fastify-table/table/funcs/getFilterSQL/index.js";
|
|
5
|
+
|
|
7
6
|
import gisIRColumn from "@opengis/fastify-table/table/controllers/utils/gisIRColumn.js";
|
|
8
|
-
|
|
7
|
+
|
|
8
|
+
import getFilterSQL from "./funcs/getFilterSQL/index.js";
|
|
9
|
+
|
|
10
|
+
import assignTokens from './utils/assignTokens.js';
|
|
9
11
|
|
|
10
12
|
const maxLimit = 100;
|
|
11
13
|
|
|
@@ -25,7 +27,7 @@ export default async function getTableData(req) {
|
|
|
25
27
|
}
|
|
26
28
|
|
|
27
29
|
const {
|
|
28
|
-
table,
|
|
30
|
+
table, sql, form, meta, sqlColumns, ispublic,
|
|
29
31
|
} = loadTable;
|
|
30
32
|
const columns = loadTable.columns || loadTable.colModel;
|
|
31
33
|
|
|
@@ -45,9 +47,6 @@ export default async function getTableData(req) {
|
|
|
45
47
|
|
|
46
48
|
const sqlTable = sql?.filter?.((el) => !el?.disabled && el?.sql?.replace).map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
|
|
47
49
|
|
|
48
|
-
const cardSqlFiltered = opt?.id || params.id ? (cardSql?.filter?.((el) => !el?.disabled && el?.name && el?.sql?.replace) || []) : [];
|
|
49
|
-
const cardSqlTable = cardSqlFiltered.length ? cardSqlFiltered.map((el, i) => ` left join lateral (select json_agg(row_to_json(q)) as ${el.name} from (${el.sql})q) ct${i} on 1=1 `).join('') || '' : '';
|
|
50
|
-
|
|
51
50
|
if (params.id && columnList.includes(params.id)) {
|
|
52
51
|
return gisIRColumn({
|
|
53
52
|
pg, funcs, layer: params.table, column: params.id, sql: query.sql,
|
|
@@ -55,6 +54,7 @@ export default async function getTableData(req) {
|
|
|
55
54
|
}
|
|
56
55
|
|
|
57
56
|
const fData = query.filter || query.search ? await getFilterSQL({
|
|
57
|
+
funcs,
|
|
58
58
|
filter: query.filter,
|
|
59
59
|
search: query.search,
|
|
60
60
|
table: params.table,
|
|
@@ -87,8 +87,7 @@ export default async function getTableData(req) {
|
|
|
87
87
|
|
|
88
88
|
const where = [(opt?.id || params.id ? ` "${pk}" = $1` : null), keyQuery, loadTable.query, fData.q, state, custom, search, access?.query || '1=1', bbox, queryPolyline].filter((el) => el);
|
|
89
89
|
|
|
90
|
-
const
|
|
91
|
-
const q = `select ${pk ? `"${pk}" as id,` : ''} ${columnList.includes('geom') ? 'st_asgeojson(geom)::json as geom,' : ''} ${query.id || query.key ? '*' : sqlColumns || cols || '*'} ${metaCols} ${cardColumns} from ${table} t ${sqlTable} ${cardSqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
|
90
|
+
const q = `select ${pk ? `"${pk}" as id,` : ''} ${columnList.includes('geom') ? 'st_asgeojson(geom)::json as geom,' : ''} ${query.id || query.key ? '*' : sqlColumns || cols || '*'} ${metaCols} from ${table} t ${sqlTable} where ${where.join(' and ') || 'true'} ${order} ${offset} limit ${limit}`;
|
|
92
91
|
|
|
93
92
|
if (query.sql === '1') { return { message: q }; }
|
|
94
93
|
|
|
@@ -99,28 +98,10 @@ export default async function getTableData(req) {
|
|
|
99
98
|
await metaFormat({ funcs, rows, table: params.table });
|
|
100
99
|
|
|
101
100
|
const res = {
|
|
102
|
-
time: Date.now() - time, card: loadTable.card, actions: loadTable.actions, access, total, count: rows.length, pk, form,
|
|
101
|
+
time: Date.now() - time, card: loadTable.card, actions: loadTable.actions, access, total, count: rows.length, pk, form, meta, columns,
|
|
103
102
|
};
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const addTokens = setToken({
|
|
107
|
-
ids: [JSON.stringify({ add: loadTable.table, form: loadTable.form })],
|
|
108
|
-
mode: 'a',
|
|
109
|
-
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
|
110
|
-
array: 1,
|
|
111
|
-
});
|
|
112
|
-
Object.assign(res, { addToken: addTokens[0] });
|
|
113
|
-
|
|
114
|
-
rows.forEach((row) => {
|
|
115
|
-
const editTokens = setToken({
|
|
116
|
-
ids: [JSON.stringify({ id: row.id, table: loadTable.table, form: loadTable.form })],
|
|
117
|
-
mode: 'w',
|
|
118
|
-
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
|
119
|
-
array: 1,
|
|
120
|
-
});
|
|
121
|
-
Object.assign(row, { token: editTokens[0] });
|
|
122
|
-
});
|
|
123
|
-
}
|
|
103
|
+
const addToken = assignTokens({ rows, funcs, ispublic, uid: 1, loadTable });
|
|
104
|
+
Object.assign(res, { rows, addToken });
|
|
124
105
|
|
|
125
106
|
return res;
|
|
126
107
|
} catch (err) {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import setToken from "@opengis/fastify-table/crud/funcs/setToken.js";
|
|
2
|
+
|
|
3
|
+
export default function assignTokens({
|
|
4
|
+
rows = [], funcs = {}, ispublic, uid, loadTable = {},
|
|
5
|
+
}) {
|
|
6
|
+
if (funcs.config?.security?.disableToken) return;
|
|
7
|
+
|
|
8
|
+
if (!funcs.config?.auth?.disable && !ispublic && !uid) throw new Error('empty user');
|
|
9
|
+
if (!loadTable?.table || !(loadTable?.form || loadTable?.add_form)) throw new Error('empty params: table/form');
|
|
10
|
+
|
|
11
|
+
const form = loadTable?.form || loadTable?.add_form;
|
|
12
|
+
const addTokens = setToken({
|
|
13
|
+
ids: [JSON.stringify({ add: loadTable.table, form })],
|
|
14
|
+
mode: 'a',
|
|
15
|
+
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
|
16
|
+
array: 1,
|
|
17
|
+
});
|
|
18
|
+
if (!rows.length) return addTokens[0];
|
|
19
|
+
|
|
20
|
+
rows.forEach((row) => {
|
|
21
|
+
const editTokens = setToken({
|
|
22
|
+
ids: [JSON.stringify({ id: row.id, table: loadTable.table, form })],
|
|
23
|
+
mode: 'w',
|
|
24
|
+
uid: funcs.config?.auth?.disable || ispublic ? '1' : uid,
|
|
25
|
+
array: 1,
|
|
26
|
+
});
|
|
27
|
+
Object.assign(row, { token: editTokens[0] });
|
|
28
|
+
});
|
|
29
|
+
return addTokens[0];
|
|
30
|
+
|
|
31
|
+
}
|