@windwalker-io/unicorn-next 0.1.0

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.
Files changed (175) hide show
  1. package/.editorconfig +18 -0
  2. package/.gulp.json +7 -0
  3. package/bin/release.mjs +47 -0
  4. package/dist/chunks/_arrayPush.js +168 -0
  5. package/dist/chunks/_arrayPush.js.map +1 -0
  6. package/dist/chunks/_baseRest.js +73 -0
  7. package/dist/chunks/_baseRest.js.map +1 -0
  8. package/dist/chunks/_commonjsHelpers.js +7 -0
  9. package/dist/chunks/_commonjsHelpers.js.map +1 -0
  10. package/dist/chunks/_getPrototype.js +130 -0
  11. package/dist/chunks/_getPrototype.js.map +1 -0
  12. package/dist/chunks/button-radio.js +147 -0
  13. package/dist/chunks/button-radio.js.map +1 -0
  14. package/dist/chunks/checkboxes-multi-select.js +44 -0
  15. package/dist/chunks/checkboxes-multi-select.js.map +1 -0
  16. package/dist/chunks/cloneDeep.js +287 -0
  17. package/dist/chunks/cloneDeep.js.map +1 -0
  18. package/dist/chunks/cropper.min.js +5 -0
  19. package/dist/chunks/cropper.min.js.map +1 -0
  20. package/dist/chunks/field-cascade-select.js +256 -0
  21. package/dist/chunks/field-cascade-select.js.map +1 -0
  22. package/dist/chunks/field-file-drag.js +218 -0
  23. package/dist/chunks/field-file-drag.js.map +1 -0
  24. package/dist/chunks/field-flatpickr.js +893 -0
  25. package/dist/chunks/field-flatpickr.js.map +1 -0
  26. package/dist/chunks/field-modal-select.js +403 -0
  27. package/dist/chunks/field-modal-select.js.map +1 -0
  28. package/dist/chunks/field-modal-tree.js +790 -0
  29. package/dist/chunks/field-modal-tree.js.map +1 -0
  30. package/dist/chunks/field-multi-uploader.js +256 -0
  31. package/dist/chunks/field-multi-uploader.js.map +1 -0
  32. package/dist/chunks/field-repeatable.js +132 -0
  33. package/dist/chunks/field-repeatable.js.map +1 -0
  34. package/dist/chunks/field-single-image-drag.js +338 -0
  35. package/dist/chunks/field-single-image-drag.js.map +1 -0
  36. package/dist/chunks/form.js +154 -0
  37. package/dist/chunks/form.js.map +1 -0
  38. package/dist/chunks/grid.js +345 -0
  39. package/dist/chunks/grid.js.map +1 -0
  40. package/dist/chunks/http-client.js +229 -0
  41. package/dist/chunks/http-client.js.map +1 -0
  42. package/dist/chunks/iframe-modal.js +124 -0
  43. package/dist/chunks/iframe-modal.js.map +1 -0
  44. package/dist/chunks/index.js +309 -0
  45. package/dist/chunks/index.js.map +1 -0
  46. package/dist/chunks/isArguments.js +146 -0
  47. package/dist/chunks/isArguments.js.map +1 -0
  48. package/dist/chunks/keep-tab.js +101 -0
  49. package/dist/chunks/keep-tab.js.map +1 -0
  50. package/dist/chunks/legacy.js +210 -0
  51. package/dist/chunks/legacy.js.map +1 -0
  52. package/dist/chunks/list-dependent.js +231 -0
  53. package/dist/chunks/list-dependent.js.map +1 -0
  54. package/dist/chunks/s3-multipart-uploader.js +172 -0
  55. package/dist/chunks/s3-multipart-uploader.js.map +1 -0
  56. package/dist/chunks/s3-uploader.js +136 -0
  57. package/dist/chunks/s3-uploader.js.map +1 -0
  58. package/dist/chunks/show-on.js +237 -0
  59. package/dist/chunks/show-on.js.map +1 -0
  60. package/dist/chunks/tinymce.js +196 -0
  61. package/dist/chunks/tinymce.js.map +1 -0
  62. package/dist/chunks/ui-bootstrap5.js +71 -0
  63. package/dist/chunks/ui-bootstrap5.js.map +1 -0
  64. package/dist/chunks/unicorn.js +2202 -0
  65. package/dist/chunks/unicorn.js.map +1 -0
  66. package/dist/chunks/validation.js +854 -0
  67. package/dist/chunks/validation.js.map +1 -0
  68. package/dist/editor.css +1 -0
  69. package/dist/index.d.ts +1427 -0
  70. package/dist/multi-level-menu.css +1 -0
  71. package/dist/switcher.css +1 -0
  72. package/dist/unicorn-next.css +12 -0
  73. package/dist/unicorn.js +125 -0
  74. package/dist/unicorn.js.map +1 -0
  75. package/fusionfile.mjs +155 -0
  76. package/images/ajax-loader.gif +0 -0
  77. package/images/placeholder/avatar.png +0 -0
  78. package/images/placeholder/image-16x10.png +0 -0
  79. package/images/placeholder/image-16x9.png +0 -0
  80. package/images/placeholder/image-1x1.png +0 -0
  81. package/images/placeholder/image-4x3.png +0 -0
  82. package/package.json +102 -0
  83. package/scss/bootstrap/multi-level-menu.scss +121 -0
  84. package/scss/editor.scss +116 -0
  85. package/scss/field/file-drag.scss +102 -0
  86. package/scss/field/single-image-drag.scss +88 -0
  87. package/scss/field/vue-drag-uploader.scss +160 -0
  88. package/scss/switcher.scss +156 -0
  89. package/src/app.ts +128 -0
  90. package/src/bootstrap/button-radio.ts +208 -0
  91. package/src/bootstrap/keep-tab.ts +155 -0
  92. package/src/composable/index.ts +21 -0
  93. package/src/composable/useCheckboxesMultiSelect.ts +22 -0
  94. package/src/composable/useFieldCascadeSelect.ts +9 -0
  95. package/src/composable/useFieldFileDrag.ts +9 -0
  96. package/src/composable/useFieldFlatpickr.ts +3 -0
  97. package/src/composable/useFieldModalSelect.ts +6 -0
  98. package/src/composable/useFieldModalTree.ts +3 -0
  99. package/src/composable/useFieldMultiUploader.ts +3 -0
  100. package/src/composable/useFieldRepeatable.ts +9 -0
  101. package/src/composable/useFieldSingleImageDrag.ts +5 -0
  102. package/src/composable/useForm.ts +43 -0
  103. package/src/composable/useGrid.ts +57 -0
  104. package/src/composable/useHttp.ts +8 -0
  105. package/src/composable/useIframeModal.ts +9 -0
  106. package/src/composable/useListDependent.ts +26 -0
  107. package/src/composable/useQueue.ts +13 -0
  108. package/src/composable/useS3Uploader.ts +32 -0
  109. package/src/composable/useShowOn.ts +9 -0
  110. package/src/composable/useStack.ts +13 -0
  111. package/src/composable/useTinymce.ts +29 -0
  112. package/src/composable/useTomSelect.ts +72 -0
  113. package/src/composable/useUIBootstrap5.ts +48 -0
  114. package/src/composable/useUniDirective.ts +32 -0
  115. package/src/composable/useValidation.ts +39 -0
  116. package/src/data.ts +36 -0
  117. package/src/events.ts +73 -0
  118. package/src/legacy/legacy.ts +186 -0
  119. package/src/legacy/loader.ts +125 -0
  120. package/src/module/checkboxes-multi-select.ts +54 -0
  121. package/src/module/field-cascade-select.ts +292 -0
  122. package/src/module/field-file-drag.ts +292 -0
  123. package/src/module/field-flatpickr.ts +127 -0
  124. package/src/module/field-modal-select.ts +174 -0
  125. package/src/module/field-modal-tree.ts +27 -0
  126. package/src/module/field-multi-uploader.ts +361 -0
  127. package/src/module/field-repeatable.ts +202 -0
  128. package/src/module/field-single-image-drag.ts +468 -0
  129. package/src/module/form.ts +223 -0
  130. package/src/module/grid.ts +465 -0
  131. package/src/module/http-client.ts +243 -0
  132. package/src/module/iframe-modal.ts +167 -0
  133. package/src/module/list-dependent.ts +321 -0
  134. package/src/module/s3-multipart-uploader.ts +300 -0
  135. package/src/module/s3-uploader.ts +234 -0
  136. package/src/module/show-on.ts +173 -0
  137. package/src/module/tinymce.ts +263 -0
  138. package/src/module/ui-bootstrap5.ts +107 -0
  139. package/src/module/validation.ts +1019 -0
  140. package/src/plugin/index.ts +1 -0
  141. package/src/plugin/php-adapter.ts +65 -0
  142. package/src/polyfill/form-request-submit.ts +31 -0
  143. package/src/polyfill/index.ts +9 -0
  144. package/src/service/animate.ts +58 -0
  145. package/src/service/crypto.ts +27 -0
  146. package/src/service/dom-watcher.ts +62 -0
  147. package/src/service/dom.ts +265 -0
  148. package/src/service/helper.ts +48 -0
  149. package/src/service/index.ts +10 -0
  150. package/src/service/lang.ts +122 -0
  151. package/src/service/loader.ts +152 -0
  152. package/src/service/router.ts +118 -0
  153. package/src/service/ui.ts +497 -0
  154. package/src/service/uri.ts +106 -0
  155. package/src/types/base.ts +9 -0
  156. package/src/types/index.ts +4 -0
  157. package/src/types/modal-tree.ts +12 -0
  158. package/src/types/plugin.ts +6 -0
  159. package/src/types/shims.d.ts +18 -0
  160. package/src/types/ui.ts +6 -0
  161. package/src/unicorn.ts +63 -0
  162. package/src/utilities/arr.ts +25 -0
  163. package/src/utilities/base.ts +9 -0
  164. package/src/utilities/data.ts +48 -0
  165. package/src/utilities/index.ts +5 -0
  166. package/src/utilities/tree.ts +20 -0
  167. package/src/vue/components/ModalTree/ModalTreeApp.vue +175 -0
  168. package/src/vue/components/ModalTree/TreeItem.vue +262 -0
  169. package/src/vue/components/ModalTree/TreeModal.vue +225 -0
  170. package/tests/test.js +4 -0
  171. package/tsconfig.js.json +25 -0
  172. package/tsconfig.json +17 -0
  173. package/vite.assets.config.ts +61 -0
  174. package/vite.config.test.ts +36 -0
  175. package/vite.config.ts +112 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-modal-tree.js","sources":["../../src/utilities/tree.ts","../../../../../../node_modules/vue3-slide-up-down/dist/vue3-slide-up-down.js","../../src/vue/components/ModalTree/TreeItem.vue","../../src/vue/components/ModalTree/TreeItem.vue","../../src/vue/components/ModalTree/TreeModal.vue","../../src/vue/components/ModalTree/TreeModal.vue","../../src/vue/components/ModalTree/ModalTreeApp.vue","../../src/vue/components/ModalTree/ModalTreeApp.vue","../../src/module/field-modal-tree.ts"],"sourcesContent":["import { TreeNode } from '../types';\r\n\r\nexport function flattenChildren(children: TreeNode[]) {\r\n const flat: TreeNode[] = [];\r\n\r\n function loopChildren(children: TreeNode[]) {\r\n for (const child of children) {\r\n if (child.children.length === 0) {\r\n flat.push(child);\r\n continue;\r\n }\r\n\r\n loopChildren(child.children);\r\n }\r\n }\r\n\r\n loopChildren(children);\r\n return flat;\r\n}\r\n\r\n","import { defineComponent as C, ref as E, computed as h, h as p, Transition as W, withDirectives as F, mergeProps as L, vShow as k, unref as b } from \"vue\";\nfunction y(t) {\n return {\n height: t.style.height,\n width: t.style.width,\n position: t.style.position,\n visibility: t.style.visibility,\n overflow: t.style.overflow,\n paddingTop: t.style.paddingTop,\n paddingBottom: t.style.paddingBottom,\n borderTopWidth: t.style.borderTopWidth,\n borderBottomWidth: t.style.borderBottomWidth,\n marginTop: t.style.marginTop,\n marginBottom: t.style.marginBottom\n };\n}\nfunction V(t, o, i) {\n const e = b(t), { width: n } = getComputedStyle(o);\n o.style.width = n, o.style.position = \"absolute\", o.style.visibility = \"hidden\", o.style.height = \"\";\n const { height: s } = getComputedStyle(o);\n return o.style.width = i.width, o.style.position = i.position, o.style.visibility = i.visibility, o.style.height = e, o.style.overflow = \"hidden\", i.height && i.height != e ? i.height : s;\n}\nfunction f(t, o, i, e, n) {\n const s = t.animate(e, n);\n t.style.height = o.height, s.onfinish = () => {\n t.style.overflow = o.overflow, i();\n };\n}\nfunction m(t, o, i, e) {\n const n = b(o);\n return [\n {\n height: n,\n opacity: t.opacityClosed,\n paddingTop: n,\n paddingBottom: n,\n borderTopWidth: n,\n borderBottomWidth: n,\n marginTop: n,\n marginBottom: n\n },\n {\n height: i,\n opacity: t.opacityOpen,\n paddingTop: e.paddingTop || 0,\n paddingBottom: e.paddingBottom || 0,\n borderTopWidth: e.borderTopWidth || 0,\n borderBottomWidth: e.borderBottomWidth || 0,\n marginTop: e.marginTop || 0,\n marginBottom: e.marginBottom || 0\n }\n ];\n}\nconst x = C({\n props: {\n modelValue: {\n type: Boolean,\n default: !1\n },\n /**\n * Time in milliseconds for the slide duration\n */\n duration: {\n type: Number,\n default: 500\n },\n /**\n * Timing function for the animation\n */\n timingFunction: {\n type: String,\n default: \"ease-in-out\"\n },\n /**\n * Independent timing function for the animation when entering\n */\n timingFunctionEnter: {\n type: String,\n default: null\n },\n /**\n * Independent timing function for the animation when leaving\n */\n timingFunctionLeave: {\n type: String,\n default: null\n },\n /**\n * Opacity value from 0 - 1 of the element when open\n */\n opacityOpen: {\n type: Number,\n default: 1\n },\n /**\n * Opacity value from 0 - 1 of the element when closed\n */\n opacityClosed: {\n type: Number,\n default: 0\n },\n /**\n * HTML tag to use for the outer container\n */\n tag: {\n type: String,\n default: \"div\"\n },\n /**\n * Always render the element inside the slide container\n */\n eager: {\n type: Boolean,\n default: !1\n }\n },\n emits: [\"update:modelValue\", \"open-start\", \"open-end\", \"close-start\", \"close-end\"],\n setup(t, { slots: o, attrs: i, emit: e }) {\n const n = E(\"0px\"), s = h(() => t.timingFunctionEnter || t.timingFunction), v = h(() => t.timingFunctionLeave || t.timingFunction);\n function T(g, l) {\n const d = g, a = y(d), r = V(n, d, a), u = m(t, n, r, a), c = { duration: t.duration, easing: s.value };\n f(d, a, () => {\n l(), e(\"open-end\");\n }, u, c);\n }\n function B(g, l) {\n const d = g, a = y(d), { height: r } = getComputedStyle(d);\n d.style.height = r, d.style.overflow = \"hidden\";\n const u = m(t, n, r, a).reverse(), c = { duration: t.duration, easing: v.value };\n f(d, a, () => {\n l(), e(\"close-end\");\n }, u, c);\n }\n return () => p(\n W,\n {\n css: !1,\n persisted: t.eager,\n onBeforeEnter: () => e(\"open-start\"),\n onEnter: T,\n onBeforeLeave: () => e(\"close-start\"),\n onLeave: B\n },\n {\n default: () => t.modelValue || t.eager ? F(\n p(\n t.tag,\n L(i, {\n class: \"slide-up-down__container\"\n }),\n o\n ),\n [t.eager ? [k, t.modelValue === !0] : [null]]\n ) : null\n }\n );\n }\n});\nexport {\n x as Vue3SlideUpDown\n};\n","<script setup lang=\"ts\">\r\nimport { type ComponentPublicInstance, type ComputedRef, computed, inject, nextTick, onBeforeUpdate, onMounted, ref, watch } from 'vue';\r\nimport { Vue3SlideUpDown } from 'vue3-slide-up-down';\r\nimport { TitleGetter, TreeNode, ValueGetter } from '../../../types';\r\nimport { flattenChildren } from '../../../utilities';\r\nimport TreeItem from './TreeItem.vue';\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n node: TreeNode;\r\n level?: number;\r\n branchSelectable?: boolean;\r\n }>(),\r\n {\r\n level: 1,\r\n branchSelectable: false,\r\n }\r\n);\r\n\r\nconst emit = defineEmits<{\r\n change: [checked: boolean];\r\n input: [checked: boolean];\r\n}>();\r\n\r\nconst node = ref<TreeNode>(props.node);\r\n// const selectNode = inject<(node: TreeNode, select: boolean) => any>('selectNode');\r\nconst selectedValues = inject<ComputedRef<(string | number)[]>>('selectedValues');\r\nconst id = inject('id');\r\nconst multiple = inject('multiple');\r\nconst valueGetter = inject<ValueGetter>('valueGetter');\r\nconst titleGetter = inject<TitleGetter>('titleGetter');\r\n\r\nconst selected = ref(false);\r\nconst indeterminate = computed(() => !!props.node.indeterminate);\r\nconst stopWatch = ref(false);\r\nconst open = ref(false);\r\nconst childrenComponents = ref<ComponentPublicInstance<typeof TreeItem>[]>([]);\r\n\r\nwatch(() => props.node, () => {\r\n selected.value = !!props.node.selected;\r\n}, { deep: true });\r\n\r\nfunction setChildrenComponent(child: ComponentPublicInstance<typeof TreeItem>) {\r\n childrenComponents.value.push(child);\r\n}\r\n\r\nonBeforeUpdate(() => {\r\n childrenComponents.value = [];\r\n});\r\n\r\nconst indentPx = computed(() => {\r\n return (props.level - 1) * 15;\r\n});\r\n\r\nconst isBranch = computed(() => {\r\n return props.node.children.length > 0;\r\n});\r\n\r\nconst isLeaf = computed(() => {\r\n return !isBranch.value;\r\n});\r\n\r\nfunction updateSelected() {\r\n if (isBranch.value) {\r\n return;\r\n }\r\n\r\n node.value.selected = selectedValues.value.includes(valueGetter(props.node.value));\r\n}\r\n\r\nfunction select(select: boolean) {\r\n if (selected.value === select) {\r\n return;\r\n }\r\n\r\n node.value.selected = select;\r\n\r\n checkboxChanged(select);\r\n}\r\n\r\nfunction checkboxChanged(v: boolean) {\r\n if (isBranch.value) {\r\n node.value.selected = v;\r\n\r\n if (multiple) {\r\n stopWatchThen(() => {\r\n const flatChildren = flattenChildren(node.value.children);\r\n for (const child of flatChildren) {\r\n child.selected = v;\r\n child.indeterminate = false;\r\n }\r\n });\r\n // syncChildrenStatus();\r\n }\r\n } else {\r\n nextTick(() => {\r\n node.value.selected = v;\r\n });\r\n }\r\n emit('change', v);\r\n emit('input', v);\r\n}\r\n\r\nfunction childChanged(v: boolean) {\r\n if (isLeaf.value || stopWatch.value) {\r\n return;\r\n }\r\n if (!childrenComponents.value) {\r\n return;\r\n }\r\n if (childrenComponents.value.length === 0) {\r\n return;\r\n }\r\n syncChildrenStatus();\r\n}\r\n\r\nfunction syncChildrenStatus() {\r\n if (isLeaf.value) {\r\n return;\r\n }\r\n let selectedCount = 0;\r\n let unselectCount = 0;\r\n let indeterminateInner = 0;\r\n const oldIndeterminate = indeterminate.value;\r\n const oldSelected = selected.value;\r\n \r\n for (const child of flattenChildren(props.node.children)) {\r\n if (child.selected) {\r\n selectedCount++;\r\n } else {\r\n unselectCount++;\r\n }\r\n\r\n if (child.indeterminate) {\r\n indeterminateInner++;\r\n }\r\n }\r\n\r\n // for (const childComponent of childrenComponents.value) {\r\n // if (childComponent.selected) {\r\n // checked++;\r\n // } else {\r\n // unchecked++;\r\n // }\r\n // if (childComponent.indeterminate) {\r\n // indeterminateInner++;\r\n // }\r\n // }\r\n\r\n if ((selectedCount !== 0 && unselectCount !== 0) || indeterminateInner > 0) {\r\n node.value.indeterminate = true;\r\n } else {\r\n node.value.selected = unselectCount === 0;\r\n node.value.indeterminate = false;\r\n }\r\n\r\n if (\r\n selected.value !== oldSelected\r\n || indeterminate.value !== oldIndeterminate\r\n ) {\r\n emit('change', selected.value);\r\n emit('input', selected.value);\r\n }\r\n}\r\n\r\nfunction stopWatchThen(callback: () => any) {\r\n stopWatch.value = true;\r\n callback();\r\n stopWatch.value = false;\r\n}\r\n\r\nwatch(() => selectedValues, async () => {\r\n if (!isBranch.value) {\r\n updateSelected();\r\n }\r\n await nextTick();\r\n\r\n syncChildrenStatus();\r\n}, { deep: true });\r\n\r\nwatch(selected, (v) => {\r\n});\r\n\r\nupdateSelected();\r\n\r\nonMounted(() => {\r\n syncChildrenStatus();\r\n});\r\n\r\ndefineExpose({\r\n select,\r\n selected,\r\n indeterminate\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"c-tree-item\"\r\n :class=\"[ isBranch ? 'c-tree-item--branch' : 'c-tree-item--leaf' ]\">\r\n <div class=\"d-flex c-tree-item__title\"\r\n :style=\"{ 'padding-left': indentPx + 'px' }\"\r\n :class=\"[ isBranch ? 'bg-light ' : '' ]\">\r\n <div class=\"p-2 ms-2\">\r\n <input\r\n :type=\"multiple ? 'checkbox' : 'radio'\"\r\n class=\"form-check-input\"\r\n v-if=\"isLeaf || (branchSelectable && multiple)\"\r\n :id=\"id + '__item-' + valueGetter(node.value)\"\r\n v-model=\"selected\"\r\n :value=\"true\"\r\n :unchecked-value=\"false\"\r\n :indeterminate.sync=\"indeterminate\"\r\n @change=\"checkboxChanged(($event.target as HTMLInputElement).checked)\"\r\n />\r\n <input v-else\r\n :type=\"multiple ? 'checkbox' : 'radio'\"\r\n class=\"form-check-input\"\r\n disabled\r\n :checked=\"indeterminate\" :indeterminate.sync=\"indeterminate\" />\r\n </div>\r\n <a class=\"c-tree-item__text d-flex align-items-center flex-grow-1 py-2 text-decoration-none\"\r\n style=\"cursor: pointer;\"\r\n :data-level=\"level\"\r\n data-bs-toggle=\"collapse\"\r\n @click.prevent=\"isLeaf ? select(!selected) : open = !open\">\r\n <span class=\"me-2 fa\" :class=\"[ isLeaf ? 'fa-tag' : 'fa-folder' ]\"></span>\r\n\r\n {{ node.value.title }}\r\n\r\n <span v-if=\"isBranch\" class=\"ms-auto me-3\">\r\n <span :class=\"[ open ? 'fa fa-chevron-up' : 'fa fa-chevron-down' ]\"></span>\r\n </span>\r\n </a>\r\n </div>\r\n\r\n <Vue3SlideUpDown\r\n v-if=\"node.children.length > 0\"\r\n v-model=\"open\"\r\n :duration=\"300\"\r\n class=\"c-tree-item__children\"\r\n >\r\n <TreeItem v-for=\"(child, i) of node.children\"\r\n :node=\"child\"\r\n :key=\"valueGetter(child.value)\"\r\n :level=\"level + 1\"\r\n :branch-selectable=\"branchSelectable\"\r\n :ref=\"setChildrenComponent\"\r\n @change=\"childChanged\"\r\n />\r\n </Vue3SlideUpDown>\r\n </div>\r\n</template>\r\n\r\n<style scoped lang=\"scss\">\r\n.c-tree-item {\r\n &__title {\r\n border-bottom: 1px solid #ddd;\r\n }\r\n\r\n cursor: pointer;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\nimport { type ComponentPublicInstance, type ComputedRef, computed, inject, nextTick, onBeforeUpdate, onMounted, ref, watch } from 'vue';\r\nimport { Vue3SlideUpDown } from 'vue3-slide-up-down';\r\nimport { TitleGetter, TreeNode, ValueGetter } from '../../../types';\r\nimport { flattenChildren } from '../../../utilities';\r\nimport TreeItem from './TreeItem.vue';\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n node: TreeNode;\r\n level?: number;\r\n branchSelectable?: boolean;\r\n }>(),\r\n {\r\n level: 1,\r\n branchSelectable: false,\r\n }\r\n);\r\n\r\nconst emit = defineEmits<{\r\n change: [checked: boolean];\r\n input: [checked: boolean];\r\n}>();\r\n\r\nconst node = ref<TreeNode>(props.node);\r\n// const selectNode = inject<(node: TreeNode, select: boolean) => any>('selectNode');\r\nconst selectedValues = inject<ComputedRef<(string | number)[]>>('selectedValues');\r\nconst id = inject('id');\r\nconst multiple = inject('multiple');\r\nconst valueGetter = inject<ValueGetter>('valueGetter');\r\nconst titleGetter = inject<TitleGetter>('titleGetter');\r\n\r\nconst selected = ref(false);\r\nconst indeterminate = computed(() => !!props.node.indeterminate);\r\nconst stopWatch = ref(false);\r\nconst open = ref(false);\r\nconst childrenComponents = ref<ComponentPublicInstance<typeof TreeItem>[]>([]);\r\n\r\nwatch(() => props.node, () => {\r\n selected.value = !!props.node.selected;\r\n}, { deep: true });\r\n\r\nfunction setChildrenComponent(child: ComponentPublicInstance<typeof TreeItem>) {\r\n childrenComponents.value.push(child);\r\n}\r\n\r\nonBeforeUpdate(() => {\r\n childrenComponents.value = [];\r\n});\r\n\r\nconst indentPx = computed(() => {\r\n return (props.level - 1) * 15;\r\n});\r\n\r\nconst isBranch = computed(() => {\r\n return props.node.children.length > 0;\r\n});\r\n\r\nconst isLeaf = computed(() => {\r\n return !isBranch.value;\r\n});\r\n\r\nfunction updateSelected() {\r\n if (isBranch.value) {\r\n return;\r\n }\r\n\r\n node.value.selected = selectedValues.value.includes(valueGetter(props.node.value));\r\n}\r\n\r\nfunction select(select: boolean) {\r\n if (selected.value === select) {\r\n return;\r\n }\r\n\r\n node.value.selected = select;\r\n\r\n checkboxChanged(select);\r\n}\r\n\r\nfunction checkboxChanged(v: boolean) {\r\n if (isBranch.value) {\r\n node.value.selected = v;\r\n\r\n if (multiple) {\r\n stopWatchThen(() => {\r\n const flatChildren = flattenChildren(node.value.children);\r\n for (const child of flatChildren) {\r\n child.selected = v;\r\n child.indeterminate = false;\r\n }\r\n });\r\n // syncChildrenStatus();\r\n }\r\n } else {\r\n nextTick(() => {\r\n node.value.selected = v;\r\n });\r\n }\r\n emit('change', v);\r\n emit('input', v);\r\n}\r\n\r\nfunction childChanged(v: boolean) {\r\n if (isLeaf.value || stopWatch.value) {\r\n return;\r\n }\r\n if (!childrenComponents.value) {\r\n return;\r\n }\r\n if (childrenComponents.value.length === 0) {\r\n return;\r\n }\r\n syncChildrenStatus();\r\n}\r\n\r\nfunction syncChildrenStatus() {\r\n if (isLeaf.value) {\r\n return;\r\n }\r\n let selectedCount = 0;\r\n let unselectCount = 0;\r\n let indeterminateInner = 0;\r\n const oldIndeterminate = indeterminate.value;\r\n const oldSelected = selected.value;\r\n \r\n for (const child of flattenChildren(props.node.children)) {\r\n if (child.selected) {\r\n selectedCount++;\r\n } else {\r\n unselectCount++;\r\n }\r\n\r\n if (child.indeterminate) {\r\n indeterminateInner++;\r\n }\r\n }\r\n\r\n // for (const childComponent of childrenComponents.value) {\r\n // if (childComponent.selected) {\r\n // checked++;\r\n // } else {\r\n // unchecked++;\r\n // }\r\n // if (childComponent.indeterminate) {\r\n // indeterminateInner++;\r\n // }\r\n // }\r\n\r\n if ((selectedCount !== 0 && unselectCount !== 0) || indeterminateInner > 0) {\r\n node.value.indeterminate = true;\r\n } else {\r\n node.value.selected = unselectCount === 0;\r\n node.value.indeterminate = false;\r\n }\r\n\r\n if (\r\n selected.value !== oldSelected\r\n || indeterminate.value !== oldIndeterminate\r\n ) {\r\n emit('change', selected.value);\r\n emit('input', selected.value);\r\n }\r\n}\r\n\r\nfunction stopWatchThen(callback: () => any) {\r\n stopWatch.value = true;\r\n callback();\r\n stopWatch.value = false;\r\n}\r\n\r\nwatch(() => selectedValues, async () => {\r\n if (!isBranch.value) {\r\n updateSelected();\r\n }\r\n await nextTick();\r\n\r\n syncChildrenStatus();\r\n}, { deep: true });\r\n\r\nwatch(selected, (v) => {\r\n});\r\n\r\nupdateSelected();\r\n\r\nonMounted(() => {\r\n syncChildrenStatus();\r\n});\r\n\r\ndefineExpose({\r\n select,\r\n selected,\r\n indeterminate\r\n});\r\n</script>\r\n\r\n<template>\r\n <div class=\"c-tree-item\"\r\n :class=\"[ isBranch ? 'c-tree-item--branch' : 'c-tree-item--leaf' ]\">\r\n <div class=\"d-flex c-tree-item__title\"\r\n :style=\"{ 'padding-left': indentPx + 'px' }\"\r\n :class=\"[ isBranch ? 'bg-light ' : '' ]\">\r\n <div class=\"p-2 ms-2\">\r\n <input\r\n :type=\"multiple ? 'checkbox' : 'radio'\"\r\n class=\"form-check-input\"\r\n v-if=\"isLeaf || (branchSelectable && multiple)\"\r\n :id=\"id + '__item-' + valueGetter(node.value)\"\r\n v-model=\"selected\"\r\n :value=\"true\"\r\n :unchecked-value=\"false\"\r\n :indeterminate.sync=\"indeterminate\"\r\n @change=\"checkboxChanged(($event.target as HTMLInputElement).checked)\"\r\n />\r\n <input v-else\r\n :type=\"multiple ? 'checkbox' : 'radio'\"\r\n class=\"form-check-input\"\r\n disabled\r\n :checked=\"indeterminate\" :indeterminate.sync=\"indeterminate\" />\r\n </div>\r\n <a class=\"c-tree-item__text d-flex align-items-center flex-grow-1 py-2 text-decoration-none\"\r\n style=\"cursor: pointer;\"\r\n :data-level=\"level\"\r\n data-bs-toggle=\"collapse\"\r\n @click.prevent=\"isLeaf ? select(!selected) : open = !open\">\r\n <span class=\"me-2 fa\" :class=\"[ isLeaf ? 'fa-tag' : 'fa-folder' ]\"></span>\r\n\r\n {{ node.value.title }}\r\n\r\n <span v-if=\"isBranch\" class=\"ms-auto me-3\">\r\n <span :class=\"[ open ? 'fa fa-chevron-up' : 'fa fa-chevron-down' ]\"></span>\r\n </span>\r\n </a>\r\n </div>\r\n\r\n <Vue3SlideUpDown\r\n v-if=\"node.children.length > 0\"\r\n v-model=\"open\"\r\n :duration=\"300\"\r\n class=\"c-tree-item__children\"\r\n >\r\n <TreeItem v-for=\"(child, i) of node.children\"\r\n :node=\"child\"\r\n :key=\"valueGetter(child.value)\"\r\n :level=\"level + 1\"\r\n :branch-selectable=\"branchSelectable\"\r\n :ref=\"setChildrenComponent\"\r\n @change=\"childChanged\"\r\n />\r\n </Vue3SlideUpDown>\r\n </div>\r\n</template>\r\n\r\n<style scoped lang=\"scss\">\r\n.c-tree-item {\r\n &__title {\r\n border-bottom: 1px solid #ddd;\r\n }\r\n\r\n cursor: pointer;\r\n}\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nimport { Modal } from 'bootstrap';\r\nimport { computed, getCurrentInstance, inject, onMounted, onUnmounted, provide, ref, useTemplateRef, watch } from 'vue';\r\nimport { useHttpClient } from '../../../composable';\r\nimport { forceArray } from '../../../service';\r\nimport { MaybeArray, ModalTreeSource, SearchMatcher, TitleGetter, TreeNode, ValueGetter } from '../../../types';\r\nimport { flattenChildren } from '../../../utilities';\r\nimport TreeItem from './TreeItem.vue';\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n open?: boolean;\r\n id?: string;\r\n name?: string;\r\n types?: string[];\r\n title?: string;\r\n disabled?: boolean;\r\n readonly?: boolean;\r\n value?: MaybeArray<string | number>;\r\n branchSelectable?: boolean;\r\n source?: ModalTreeSource;\r\n searchText?: string;\r\n }>(),\r\n {\r\n branchSelectable: false,\r\n }\r\n);\r\n\r\nconst emits = defineEmits<{\r\n change: [value: any];\r\n input: [value: any];\r\n selected: [items: any[]];\r\n hide: [];\r\n}>();\r\n\r\n// provide('selectNode', selectNode);\r\n\r\nconst valueGetter = inject<ValueGetter>('valueGetter');\r\nconst titleGetter = inject<TitleGetter>('titleGetter');\r\nconst searchMatcher = inject<SearchMatcher>('searchMatcher');\r\n\r\nconst loading = ref(false);\r\nconst multiple = inject<boolean>('multiple', false);\r\nconst modalElement = useTemplateRef<HTMLDivElement>('modal')\r\n\r\nlet $modal: Modal;\r\n\r\nonMounted(() => {\r\n $modal = Modal.getOrCreateInstance(modalElement.value!);\r\n modalElement.value!.addEventListener('show.bs.modal', onShow);\r\n modalElement.value!.addEventListener('hide.bs.modal', onHide);\r\n});\r\n\r\nonUnmounted(() => {\r\n modalElement.value!.removeEventListener('show.bs.modal', onShow);\r\n modalElement.value!.removeEventListener('hide.bs.modal', onHide);\r\n});\r\n\r\n// Items\r\nconst nodes = ref<TreeNode[]>([]);\r\nconst selectedNodes = ref<TreeNode[]>([]);\r\n\r\nconst displayNodes = computed(() => {\r\n if (searchEnabled.value) {\r\n return searchedItems.value;\r\n }\r\n return nodes.value;\r\n});\r\n\r\nconst flatNodes = computed(() => flattenChildren(nodes.value));\r\n\r\nconst selectedValues = computed(() => {\r\n return flatNodes.value.filter((node) => node.selected).map((node) => valueGetter(node.value));\r\n});\r\n\r\nprovide('selectedValues', selectedValues);\r\n\r\nwatch(() => selectedValues, () => {\r\n emits('change', selectedValues.value);\r\n emits('input', selectedValues.value);\r\n emits('selected', selectedNodes.value);\r\n});\r\n\r\n// function selectNode(node: TreeNode, select: boolean) {\r\n// node.selected = select;\r\n//\r\n// // if (select) {\r\n// // if (!multiple) {\r\n// // selectedNodes.value = [];\r\n// // }\r\n// // if (!selectedValues.value.includes(valueGetter(node.value))) {\r\n// // selectedNodes.value.push(node);\r\n// // }\r\n// // } else {\r\n// // selectedNodes.value = selectedNodes.value.filter(\r\n// // (selectedNode: TreeNode) => valueGetter(selectedNode.value) !== valueGetter(node.value)\r\n// // );\r\n// // }\r\n// emits('change', selectedValues.value);\r\n// emits('input', selectedValues.value);\r\n// emits('selected', selectedNodes.value);\r\n// }\r\n\r\nconst canModify = computed(() => {\r\n return !props.readonly && !props.disabled;\r\n});\r\n\r\n// Search\r\nconst q = ref('');\r\nconst searchEnabled = computed(() => q.value !== '');\r\n\r\nconst searchedItems = computed(() => {\r\n if (q.value === '') {\r\n return [];\r\n }\r\n\r\n return flatNodes.value.filter((item: TreeNode) => {\r\n return searchMatcher(item.value, q.value);\r\n });\r\n});\r\n\r\nasync function loadItems() {\r\n loading.value = true;\r\n const http = await useHttpClient();\r\n try {\r\n let src = props.source;\r\n\r\n if (typeof src === 'string') {\r\n const res = await http.get(src);\r\n nodes.value = res.data.data;\r\n } else if (typeof src === 'function') {\r\n nodes.value = await src();\r\n } else {\r\n if (!Array.isArray(src)) {\r\n src = src.children;\r\n }\r\n\r\n nodes.value = src;\r\n }\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\n// Modal Control\r\nwatch(() => props.open, (v) => {\r\n if (v) {\r\n $modal.show();\r\n } else {\r\n $modal.hide();\r\n }\r\n});\r\n\r\nasync function onShow() {\r\n await loadItems();\r\n updateSelectedItemsByValue();\r\n}\r\n\r\nfunction onHide() {\r\n nodes.value = [];\r\n q.value = '';\r\n emits('hide');\r\n}\r\n\r\nfunction updateSelectedItemsByValue() {\r\n const values = forceArray(props.value);\r\n\r\n selectedNodes.value = flatNodes.value\r\n .filter((item: TreeNode) => {\r\n return values.includes(valueGetter(item.value));\r\n });\r\n}\r\n\r\nwatch(\r\n () => props.value,\r\n () => updateSelectedItemsByValue(),\r\n { immediate: true, deep: true }\r\n);\r\n\r\n</script>\r\n\r\n<template>\r\n <div ref=\"modal\" class=\"modal fade\" :id=\"`${id}__modal`\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"-modal-label\"\r\n aria-hidden=\"true\">\r\n <div class=\"modal-dialog\" role=\"document\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" :id=\"`${id}__modal-label`\">\r\n {{ title }}\r\n </h4>\r\n <button type=\"button\" class=\"close btn-close\" data-bs-dismiss=\"modal\" data-dismiss=\"modal\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\" class=\"visually-hidden\">&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"modal-body p-0\">\r\n <div class=\"std-form box-list m-3\">\r\n <div class=\"form-group\">\r\n <input type=\"search\" class=\"form-control\" :placeholder=\"searchText\"\r\n v-model=\"q\" />\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"!loading\" class=\"box-list__items\">\r\n <TreeItem v-for=\"node of displayNodes\"\r\n :node\r\n :key=\"valueGetter(node.value)\"\r\n :level=\"1\"\r\n :branchSelectable\r\n />\r\n </div>\r\n <div v-else>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border spinner-border-sm my-3\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nimport { Modal } from 'bootstrap';\r\nimport { computed, getCurrentInstance, inject, onMounted, onUnmounted, provide, ref, useTemplateRef, watch } from 'vue';\r\nimport { useHttpClient } from '../../../composable';\r\nimport { forceArray } from '../../../service';\r\nimport { MaybeArray, ModalTreeSource, SearchMatcher, TitleGetter, TreeNode, ValueGetter } from '../../../types';\r\nimport { flattenChildren } from '../../../utilities';\r\nimport TreeItem from './TreeItem.vue';\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n open?: boolean;\r\n id?: string;\r\n name?: string;\r\n types?: string[];\r\n title?: string;\r\n disabled?: boolean;\r\n readonly?: boolean;\r\n value?: MaybeArray<string | number>;\r\n branchSelectable?: boolean;\r\n source?: ModalTreeSource;\r\n searchText?: string;\r\n }>(),\r\n {\r\n branchSelectable: false,\r\n }\r\n);\r\n\r\nconst emits = defineEmits<{\r\n change: [value: any];\r\n input: [value: any];\r\n selected: [items: any[]];\r\n hide: [];\r\n}>();\r\n\r\n// provide('selectNode', selectNode);\r\n\r\nconst valueGetter = inject<ValueGetter>('valueGetter');\r\nconst titleGetter = inject<TitleGetter>('titleGetter');\r\nconst searchMatcher = inject<SearchMatcher>('searchMatcher');\r\n\r\nconst loading = ref(false);\r\nconst multiple = inject<boolean>('multiple', false);\r\nconst modalElement = useTemplateRef<HTMLDivElement>('modal')\r\n\r\nlet $modal: Modal;\r\n\r\nonMounted(() => {\r\n $modal = Modal.getOrCreateInstance(modalElement.value!);\r\n modalElement.value!.addEventListener('show.bs.modal', onShow);\r\n modalElement.value!.addEventListener('hide.bs.modal', onHide);\r\n});\r\n\r\nonUnmounted(() => {\r\n modalElement.value!.removeEventListener('show.bs.modal', onShow);\r\n modalElement.value!.removeEventListener('hide.bs.modal', onHide);\r\n});\r\n\r\n// Items\r\nconst nodes = ref<TreeNode[]>([]);\r\nconst selectedNodes = ref<TreeNode[]>([]);\r\n\r\nconst displayNodes = computed(() => {\r\n if (searchEnabled.value) {\r\n return searchedItems.value;\r\n }\r\n return nodes.value;\r\n});\r\n\r\nconst flatNodes = computed(() => flattenChildren(nodes.value));\r\n\r\nconst selectedValues = computed(() => {\r\n return flatNodes.value.filter((node) => node.selected).map((node) => valueGetter(node.value));\r\n});\r\n\r\nprovide('selectedValues', selectedValues);\r\n\r\nwatch(() => selectedValues, () => {\r\n emits('change', selectedValues.value);\r\n emits('input', selectedValues.value);\r\n emits('selected', selectedNodes.value);\r\n});\r\n\r\n// function selectNode(node: TreeNode, select: boolean) {\r\n// node.selected = select;\r\n//\r\n// // if (select) {\r\n// // if (!multiple) {\r\n// // selectedNodes.value = [];\r\n// // }\r\n// // if (!selectedValues.value.includes(valueGetter(node.value))) {\r\n// // selectedNodes.value.push(node);\r\n// // }\r\n// // } else {\r\n// // selectedNodes.value = selectedNodes.value.filter(\r\n// // (selectedNode: TreeNode) => valueGetter(selectedNode.value) !== valueGetter(node.value)\r\n// // );\r\n// // }\r\n// emits('change', selectedValues.value);\r\n// emits('input', selectedValues.value);\r\n// emits('selected', selectedNodes.value);\r\n// }\r\n\r\nconst canModify = computed(() => {\r\n return !props.readonly && !props.disabled;\r\n});\r\n\r\n// Search\r\nconst q = ref('');\r\nconst searchEnabled = computed(() => q.value !== '');\r\n\r\nconst searchedItems = computed(() => {\r\n if (q.value === '') {\r\n return [];\r\n }\r\n\r\n return flatNodes.value.filter((item: TreeNode) => {\r\n return searchMatcher(item.value, q.value);\r\n });\r\n});\r\n\r\nasync function loadItems() {\r\n loading.value = true;\r\n const http = await useHttpClient();\r\n try {\r\n let src = props.source;\r\n\r\n if (typeof src === 'string') {\r\n const res = await http.get(src);\r\n nodes.value = res.data.data;\r\n } else if (typeof src === 'function') {\r\n nodes.value = await src();\r\n } else {\r\n if (!Array.isArray(src)) {\r\n src = src.children;\r\n }\r\n\r\n nodes.value = src;\r\n }\r\n } finally {\r\n loading.value = false;\r\n }\r\n}\r\n\r\n// Modal Control\r\nwatch(() => props.open, (v) => {\r\n if (v) {\r\n $modal.show();\r\n } else {\r\n $modal.hide();\r\n }\r\n});\r\n\r\nasync function onShow() {\r\n await loadItems();\r\n updateSelectedItemsByValue();\r\n}\r\n\r\nfunction onHide() {\r\n nodes.value = [];\r\n q.value = '';\r\n emits('hide');\r\n}\r\n\r\nfunction updateSelectedItemsByValue() {\r\n const values = forceArray(props.value);\r\n\r\n selectedNodes.value = flatNodes.value\r\n .filter((item: TreeNode) => {\r\n return values.includes(valueGetter(item.value));\r\n });\r\n}\r\n\r\nwatch(\r\n () => props.value,\r\n () => updateSelectedItemsByValue(),\r\n { immediate: true, deep: true }\r\n);\r\n\r\n</script>\r\n\r\n<template>\r\n <div ref=\"modal\" class=\"modal fade\" :id=\"`${id}__modal`\" tabindex=\"-1\" role=\"dialog\" aria-labelledby=\"-modal-label\"\r\n aria-hidden=\"true\">\r\n <div class=\"modal-dialog\" role=\"document\">\r\n <div class=\"modal-content\">\r\n <div class=\"modal-header\">\r\n <h4 class=\"modal-title\" :id=\"`${id}__modal-label`\">\r\n {{ title }}\r\n </h4>\r\n <button type=\"button\" class=\"close btn-close\" data-bs-dismiss=\"modal\" data-dismiss=\"modal\" aria-label=\"Close\">\r\n <span aria-hidden=\"true\" class=\"visually-hidden\">&times;</span>\r\n </button>\r\n </div>\r\n\r\n <div class=\"modal-body p-0\">\r\n <div class=\"std-form box-list m-3\">\r\n <div class=\"form-group\">\r\n <input type=\"search\" class=\"form-control\" :placeholder=\"searchText\"\r\n v-model=\"q\" />\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"!loading\" class=\"box-list__items\">\r\n <TreeItem v-for=\"node of displayNodes\"\r\n :node\r\n :key=\"valueGetter(node.value)\"\r\n :level=\"1\"\r\n :branchSelectable\r\n />\r\n </div>\r\n <div v-else>\r\n <div class=\"d-flex justify-content-center\">\r\n <div class=\"spinner-border spinner-border-sm my-3\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nimport { cloneDeep } from 'lodash-es';\r\nimport { computed, provide, ref, watch } from 'vue';\r\nimport { forceArray } from '../../../service';\r\nimport {\r\n ValueGetter,\r\n ModalTreeSource,\r\n TitleGetter,\r\n TreeNode,\r\n SearchMatcher,\r\n MaybeArray,\r\n MaybePromise\r\n} from '../../../types';\r\nimport TreeModal from './TreeModal.vue';\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n id?: string;\r\n name?: string;\r\n title?: string;\r\n disabled?: boolean;\r\n readonly?: boolean;\r\n value?: MaybeArray<string | number>;\r\n source?: ModalTreeSource;\r\n items?: MaybeArray<TreeNode> | (() => MaybePromise<MaybeArray<TreeNode>>);\r\n valueGetter?: ValueGetter;\r\n titleGetter?: TitleGetter;\r\n searchMatcher?: SearchMatcher;\r\n modalTitle?: string;\r\n vertical?: boolean;\r\n branchSelectable?: boolean;\r\n selectAllChildren?: boolean;\r\n placeholder?: string;\r\n multiple?: boolean;\r\n buttonText?: string;\r\n itemClass?: string;\r\n searchText?: string;\r\n }>(),\r\n {\r\n branchSelectable: false,\r\n selectAllChildren: false,\r\n placeholder: '- No selected -',\r\n multiple: false,\r\n buttonText: 'Select',\r\n itemClass: 'badge bg-primary badge-pill',\r\n searchText: 'Search',\r\n valueGetter: (item: any) => item.id,\r\n titleGetter: (item: any) => item.title,\r\n }\r\n);\r\n\r\nprovide('id', props.id);\r\nprovide('name', props.name);\r\nprovide('multiple', props.multiple);\r\nprovide('valueGetter', props.valueGetter);\r\nprovide('titleGetter', props.titleGetter);\r\nprovide('searchMatcher', props.searchMatcher ?? defaultSearchMatcher);\r\n\r\nfunction defaultSearchMatcher(item: any, q: string) {\r\n return props.titleGetter(item).toLowerCase().includes(q.toLowerCase());\r\n}\r\n\r\nconst selected = ref<TreeNode[]>([]);\r\nconst value = ref<(string|number)[]>(forceArray(props.value));\r\n\r\n// Modal\r\nconst treeModalOpen = ref(false);\r\n\r\nfunction openSelector() {\r\n treeModalOpen.value = true;\r\n}\r\n\r\nfunction deleteItem(i: number, node: TreeNode) {\r\n selected.value = selected.value.filter((it: TreeNode) => props.valueGetter(it.value) !== props.valueGetter(node.value));\r\n}\r\n\r\nfunction handleSelected(items: any[]) {\r\n selected.value = cloneDeep(items);\r\n}\r\n\r\nwatch(() => props.items, async (v) => {\r\n if (typeof v === 'function') {\r\n v = await v();\r\n }\r\n\r\n selected.value = forceArray(v).filter((node: TreeNode) => {\r\n return value.value.includes(props.valueGetter(node.value));\r\n });\r\n}, { immediate: true });\r\n\r\nconst selectedValues = computed(() => {\r\n return selected.value.map(node => props.valueGetter(node.value));\r\n});\r\n\r\nconst canModify = computed(() => {\r\n return !props.readonly && !props.disabled;\r\n});\r\n\r\n</script>\r\n\r\n<template>\r\n <div class=\"c-modal-tree\">\r\n <div class=\"c-modal-tree__container p-2 d-flex flex-column\"\r\n :class=\"[ vertical ? '' : 'flex-md-row' ]\">\r\n <div v-if=\"canModify\" class=\"me-2 mb-2\"\r\n :class=\"{ 'mb-md-0': !vertical }\">\r\n <div class=\"btn-group\">\r\n <button class=\"btn btn-secondary btn-sm btn-rounded text-nowrap\" type=\"button\"\r\n @click=\"openSelector\">\r\n {{ buttonText }}\r\n </button>\r\n <button class=\"btn btn-secondary btn-sm btn-rounded\" type=\"button\"\r\n @click=\"selected = []\">\r\n <span class=\"fa fa-times\"></span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"selected.length > 0\">\r\n <TransitionGroup name=\"fade\">\r\n <span v-for=\"(node, i) of selected\"\r\n class=\"me-2 mb-2 c-item\"\r\n :class=\"itemClass\"\r\n :key=\"valueGetter(node.value)\"\r\n style=\"animation-duration: .3s\">\r\n <span>{{ titleGetter(node.value) }}</span>\r\n <span type=\"button\" v-if=\"canModify\"\r\n @click.prevent=\"deleteItem(i, node)\" class=\"ms-2\" style=\"cursor: pointer\">\r\n <span class=\"fa fa-times\"></span>\r\n </span>\r\n </span>\r\n </TransitionGroup>\r\n </div>\r\n <div v-else class=\"text-muted\">\r\n {{ placeholder }}\r\n </div>\r\n </div>\r\n\r\n <select multiple\r\n style=\"display: none;\"\r\n ref=\"input\"\r\n :id=\"id\"\r\n :name=\"name\"\r\n :disabled=\"disabled\"\r\n :readonly=\"readonly\"\r\n v-bind=\"$attrs\"\r\n >\r\n <option v-for=\"id of selectedValues\" :value=\"id\" :selected=\"true\">{{ id }}</option>\r\n </select>\r\n\r\n <TreeModal\r\n :open=\"treeModalOpen\"\r\n @hide=\"treeModalOpen = false\"\r\n :id=\"id\"\r\n :title=\"modalTitle\"\r\n :source=\"source\"\r\n :value=\"selectedValues\"\r\n :branchSelectable\r\n v-bind=\"$attrs\"\r\n :disabled=\"disabled\"\r\n :readonly=\"readonly\"\r\n :search-text=\"searchText\"\r\n @selected=\"handleSelected\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.c-item {\r\n padding-left: .75rem;\r\n padding-right: .75rem;\r\n padding-top: .5rem;\r\n padding-bottom: .5rem;\r\n}\r\n</style>\r\n","<script lang=\"ts\" setup>\r\nimport { cloneDeep } from 'lodash-es';\r\nimport { computed, provide, ref, watch } from 'vue';\r\nimport { forceArray } from '../../../service';\r\nimport {\r\n ValueGetter,\r\n ModalTreeSource,\r\n TitleGetter,\r\n TreeNode,\r\n SearchMatcher,\r\n MaybeArray,\r\n MaybePromise\r\n} from '../../../types';\r\nimport TreeModal from './TreeModal.vue';\r\n\r\nconst props = withDefaults(\r\n defineProps<{\r\n id?: string;\r\n name?: string;\r\n title?: string;\r\n disabled?: boolean;\r\n readonly?: boolean;\r\n value?: MaybeArray<string | number>;\r\n source?: ModalTreeSource;\r\n items?: MaybeArray<TreeNode> | (() => MaybePromise<MaybeArray<TreeNode>>);\r\n valueGetter?: ValueGetter;\r\n titleGetter?: TitleGetter;\r\n searchMatcher?: SearchMatcher;\r\n modalTitle?: string;\r\n vertical?: boolean;\r\n branchSelectable?: boolean;\r\n selectAllChildren?: boolean;\r\n placeholder?: string;\r\n multiple?: boolean;\r\n buttonText?: string;\r\n itemClass?: string;\r\n searchText?: string;\r\n }>(),\r\n {\r\n branchSelectable: false,\r\n selectAllChildren: false,\r\n placeholder: '- No selected -',\r\n multiple: false,\r\n buttonText: 'Select',\r\n itemClass: 'badge bg-primary badge-pill',\r\n searchText: 'Search',\r\n valueGetter: (item: any) => item.id,\r\n titleGetter: (item: any) => item.title,\r\n }\r\n);\r\n\r\nprovide('id', props.id);\r\nprovide('name', props.name);\r\nprovide('multiple', props.multiple);\r\nprovide('valueGetter', props.valueGetter);\r\nprovide('titleGetter', props.titleGetter);\r\nprovide('searchMatcher', props.searchMatcher ?? defaultSearchMatcher);\r\n\r\nfunction defaultSearchMatcher(item: any, q: string) {\r\n return props.titleGetter(item).toLowerCase().includes(q.toLowerCase());\r\n}\r\n\r\nconst selected = ref<TreeNode[]>([]);\r\nconst value = ref<(string|number)[]>(forceArray(props.value));\r\n\r\n// Modal\r\nconst treeModalOpen = ref(false);\r\n\r\nfunction openSelector() {\r\n treeModalOpen.value = true;\r\n}\r\n\r\nfunction deleteItem(i: number, node: TreeNode) {\r\n selected.value = selected.value.filter((it: TreeNode) => props.valueGetter(it.value) !== props.valueGetter(node.value));\r\n}\r\n\r\nfunction handleSelected(items: any[]) {\r\n selected.value = cloneDeep(items);\r\n}\r\n\r\nwatch(() => props.items, async (v) => {\r\n if (typeof v === 'function') {\r\n v = await v();\r\n }\r\n\r\n selected.value = forceArray(v).filter((node: TreeNode) => {\r\n return value.value.includes(props.valueGetter(node.value));\r\n });\r\n}, { immediate: true });\r\n\r\nconst selectedValues = computed(() => {\r\n return selected.value.map(node => props.valueGetter(node.value));\r\n});\r\n\r\nconst canModify = computed(() => {\r\n return !props.readonly && !props.disabled;\r\n});\r\n\r\n</script>\r\n\r\n<template>\r\n <div class=\"c-modal-tree\">\r\n <div class=\"c-modal-tree__container p-2 d-flex flex-column\"\r\n :class=\"[ vertical ? '' : 'flex-md-row' ]\">\r\n <div v-if=\"canModify\" class=\"me-2 mb-2\"\r\n :class=\"{ 'mb-md-0': !vertical }\">\r\n <div class=\"btn-group\">\r\n <button class=\"btn btn-secondary btn-sm btn-rounded text-nowrap\" type=\"button\"\r\n @click=\"openSelector\">\r\n {{ buttonText }}\r\n </button>\r\n <button class=\"btn btn-secondary btn-sm btn-rounded\" type=\"button\"\r\n @click=\"selected = []\">\r\n <span class=\"fa fa-times\"></span>\r\n </button>\r\n </div>\r\n </div>\r\n\r\n <div v-if=\"selected.length > 0\">\r\n <TransitionGroup name=\"fade\">\r\n <span v-for=\"(node, i) of selected\"\r\n class=\"me-2 mb-2 c-item\"\r\n :class=\"itemClass\"\r\n :key=\"valueGetter(node.value)\"\r\n style=\"animation-duration: .3s\">\r\n <span>{{ titleGetter(node.value) }}</span>\r\n <span type=\"button\" v-if=\"canModify\"\r\n @click.prevent=\"deleteItem(i, node)\" class=\"ms-2\" style=\"cursor: pointer\">\r\n <span class=\"fa fa-times\"></span>\r\n </span>\r\n </span>\r\n </TransitionGroup>\r\n </div>\r\n <div v-else class=\"text-muted\">\r\n {{ placeholder }}\r\n </div>\r\n </div>\r\n\r\n <select multiple\r\n style=\"display: none;\"\r\n ref=\"input\"\r\n :id=\"id\"\r\n :name=\"name\"\r\n :disabled=\"disabled\"\r\n :readonly=\"readonly\"\r\n v-bind=\"$attrs\"\r\n >\r\n <option v-for=\"id of selectedValues\" :value=\"id\" :selected=\"true\">{{ id }}</option>\r\n </select>\r\n\r\n <TreeModal\r\n :open=\"treeModalOpen\"\r\n @hide=\"treeModalOpen = false\"\r\n :id=\"id\"\r\n :title=\"modalTitle\"\r\n :source=\"source\"\r\n :value=\"selectedValues\"\r\n :branchSelectable\r\n v-bind=\"$attrs\"\r\n :disabled=\"disabled\"\r\n :readonly=\"readonly\"\r\n :search-text=\"searchText\"\r\n @selected=\"handleSelected\"\r\n />\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.c-item {\r\n padding-left: .75rem;\r\n padding-right: .75rem;\r\n padding-top: .5rem;\r\n padding-bottom: .5rem;\r\n}\r\n</style>\r\n","import { data } from '../data';\r\nimport { useCssImport } from '../service';\r\nimport { createApp } from 'vue';\r\nimport ModalTreeApp from '../vue/components/ModalTree/ModalTreeApp.vue';\r\nuseCssImport('@vue-animate');\r\n\r\nconst app = createApp({\r\n name: 'modal-tree',\r\n components: {\r\n ModalTreeApp\r\n }\r\n});\r\napp.config.globalProperties.$getData = data;\r\n\r\nclass ModalTreeElement extends HTMLElement {\r\n static is = 'modal-tree';\r\n\r\n vm: any;\r\n\r\n connectedCallback() {\r\n if (!this.vm) {\r\n this.vm = app.mount(this);\r\n }\r\n }\r\n}\r\n\r\ncustomElements.define(ModalTreeElement.is, ModalTreeElement);\r\n"],"names":["children","b","C","E","h","p","W","F","L","k","select","_hoisted_1","_createElementBlock","_normalizeClass","_createElementVNode","_normalizeStyle","_withDirectives","_openBlock","_hoisted_2","_hoisted_3","_createTextVNode","_toDisplayString","_hoisted_5","_createBlock","_Fragment","_renderList","_hoisted_4","_hoisted_6","_hoisted_7","_createVNode","_TransitionGroup","_withCtx","_withModifiers","_createCommentVNode","_mergeProps"],"mappings":"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","x_google_ignoreList":[1]}
@@ -0,0 +1,256 @@
1
+ import { Modal } from "bootstrap";
2
+ import { createApp, defineComponent, ref, getCurrentInstance, useTemplateRef, computed, onMounted, nextTick } from "vue";
3
+ import { VueDraggable } from "vue-draggable-plus";
4
+ import { ItemCardPlaceholder, ItemCard, MultiUploader, createItem } from "vue-multi-uploader";
5
+ import { a7 as injectCssToDocument, a5 as mergeDeep, ab as forceArray, aa as data, m as useStack } from "./unicorn.js";
6
+ const css = ".vue-drag-uploader {\n --vmu-img-size: 155px;\n display: flex;\n flex-wrap: wrap;\n padding: 1rem;\n border: 1px dotted #999;\n border-radius: 4px;\n cursor: pointer;\n color: #999;\n min-height: 250px;\n}\n.vue-drag-uploader--readonly {\n border: 1px solid #999;\n}\n.vue-drag-uploader.h-ondrag {\n border: 1px dotted #666;\n background-color: rgba(0, 0, 0, 0.05);\n color: #666;\n}\n.vue-drag-uploader__wrapper {\n width: 100%;\n}\n.vue-drag-uploader__draggable-wrapper, .vue-drag-uploader__transition-wrapper {\n display: flex;\n flex-wrap: wrap;\n}\n.vue-drag-uploader-item {\n width: var(--vmu-img-size);\n height: var(--vmu-img-size);\n border: 1px solid rgba(0, 0, 0, 0.25);\n border-radius: 3px;\n cursor: pointer;\n padding: 0.5rem;\n}\n.vue-drag-uploader .add-button {\n display: flex;\n align-items: center;\n text-align: center;\n transition: background-color 0.5s;\n}\n.vue-drag-uploader .add-button:hover {\n background-color: rgba(0, 0, 0, 0.05);\n}\n.vue-drag-uploader .add-button__body {\n margin: 0 auto;\n}\n.vue-drag-uploader .add-button__icon {\n margin-bottom: 10px;\n}\n.vue-drag-uploader .add-button__text {\n font-size: 14px;\n}\n.vue-drag-uploader .preview-img {\n position: relative;\n cursor: pointer;\n padding: 1px;\n}\n.vue-drag-uploader .preview-img > * {\n position: absolute;\n}\n.vue-drag-uploader .preview-img:hover .error-message__message {\n display: block;\n padding: 10px;\n}\n.vue-drag-uploader .preview-img__body {\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n background: transparent no-repeat center center;\n background-size: cover;\n}\n.vue-drag-uploader .preview-img__title {\n margin: 0 auto;\n}\n.vue-drag-uploader .preview-img__overlay {\n display: flex;\n align-items: center;\n left: 0;\n top: 0;\n bottom: 0;\n right: 0;\n background-color: rgba(0, 0, 0, 0.35);\n opacity: 0;\n transition: opacity 0.5s;\n}\n.vue-drag-uploader .preview-img__overlay:hover {\n opacity: 1;\n}\n.vue-drag-uploader .preview-img__remove-icon {\n position: absolute;\n top: 5px;\n right: 5px;\n color: white;\n opacity: 0.75;\n transition: opacity 0.5s;\n}\n.vue-drag-uploader .preview-img__remove-icon:hover {\n opacity: 1;\n}\n.vue-drag-uploader .preview-img__progress {\n height: 5px;\n background-color: rgba(255, 255, 255, 0.8);\n width: 100%;\n bottom: 0;\n left: 0;\n}\n.vue-drag-uploader .preview-img__progress-bar {\n background-color: var(--bs-primary, #007bff);\n width: 0;\n height: 100%;\n}\n.vue-drag-uploader .error-message {\n width: 100%;\n background-color: #dc3545;\n color: white;\n font-size: 14px;\n word-break: break-all;\n top: calc(100% - 26px);\n min-height: 26px;\n}\n.vue-drag-uploader .error-message__notice {\n display: inline-block;\n padding: 3px;\n text-align: center;\n width: 100%;\n}\n.vue-drag-uploader .error-message__message {\n display: none;\n}";
7
+ /* @__PURE__ */ injectCssToDocument(css);
8
+ const defaultOptions = {
9
+ readonly: false,
10
+ disabled: false,
11
+ sortable: false,
12
+ thumbSize: 150,
13
+ maxConcurrent: 5,
14
+ canReplace: false,
15
+ tmplSelector: "#multi-uploader-field-tmpl"
16
+ };
17
+ class MultiUploaderElement extends HTMLElement {
18
+ static is = "uni-multi-uploader";
19
+ modalElement;
20
+ vm;
21
+ async connectedCallback() {
22
+ let options = JSON.parse(
23
+ this.getAttribute("options") || "{}"
24
+ );
25
+ const resolvedOptions = mergeDeep({}, defaultOptions, options);
26
+ resolvedOptions.thumbSize ??= 150;
27
+ this.modalElement = this.querySelector(".modal");
28
+ const tmplSelector = resolvedOptions.tmplSelector;
29
+ const app = createApp(
30
+ createAppInstance(resolvedOptions, document.querySelector(tmplSelector).innerHTML, this)
31
+ );
32
+ this.vm = app.mount(this);
33
+ }
34
+ }
35
+ /* @__PURE__ */ customElements.define(/* @__PURE__ */ (() => MultiUploaderElement.is)(), MultiUploaderElement);
36
+ function createAppInstance(opt, tmpl, el) {
37
+ return defineComponent({
38
+ name: "MultiUploaderFieldApp",
39
+ template: tmpl,
40
+ components: {
41
+ VueDraggable,
42
+ MultiUploader,
43
+ ItemCard,
44
+ ItemCardPlaceholder
45
+ },
46
+ props: {
47
+ stackName: String
48
+ },
49
+ setup(props, { expose }) {
50
+ const options = ref(opt);
51
+ const current = ref();
52
+ const currentIndex = ref();
53
+ const loading = ref(false);
54
+ const dragarea = ref();
55
+ const modal = ref();
56
+ const app = getCurrentInstance();
57
+ const uploader = useTemplateRef("uploader");
58
+ const canModify = computed(() => !options.value.disabled && !options.value.readonly);
59
+ const instance = ref();
60
+ onMounted(() => {
61
+ instance.value = uploader.value.instance;
62
+ domEmit("multi-uploader:mounted", { app, uploader });
63
+ });
64
+ const items = ref([]);
65
+ for (let item of forceArray(options.value.value)) {
66
+ if (typeof item === "string") {
67
+ item = {
68
+ url: item
69
+ };
70
+ }
71
+ const uploadItem = createItem({
72
+ url: item.url || "",
73
+ thumbUrl: item.thumbUrl || item.thumb_url || item.url || "",
74
+ data: item
75
+ });
76
+ items.value.push(uploadItem);
77
+ }
78
+ const uploadUrl = options.value.uploadUrl;
79
+ const value = items.value;
80
+ const uploaderOptions = ref({
81
+ maxFiles: () => options.value.maxFiles,
82
+ readonly: () => options.value.readonly,
83
+ disabled: () => options.value.disabled,
84
+ accept: () => options.value.accept,
85
+ maxConcurrent: () => options.value.maxConcurrent,
86
+ prepareXhr(xhr) {
87
+ xhr.setRequestHeader(
88
+ "X-CSRF-TOKEN",
89
+ data("csrf-token")
90
+ );
91
+ },
92
+ onItemUploadSuccess(item, xhr) {
93
+ const res = JSON.parse(xhr.responseText);
94
+ item.url = res.data.url;
95
+ item.thumbUrl = res.data.thumbUrl || res.data.thumb_url || res.data.url;
96
+ item.data = res.data;
97
+ item.data.title ??= item.url.split("/").pop()?.split("?").shift() || "";
98
+ }
99
+ });
100
+ const draggableOptions = {
101
+ draggable: ".c-drag-item",
102
+ animation: 300,
103
+ disabled: !canModify.value
104
+ };
105
+ function openFile(item) {
106
+ if (options.value.openFileHandler) {
107
+ options.value.openFileHandler(item);
108
+ } else {
109
+ window.open(item.download_url || item.url);
110
+ }
111
+ }
112
+ async function itemClick(item, i, event) {
113
+ current.value = item;
114
+ currentIndex.value = i;
115
+ domEmit("item-click", { item, i });
116
+ nextTick().then(() => {
117
+ Modal.getOrCreateInstance(modal.value).show();
118
+ });
119
+ }
120
+ function metaSave() {
121
+ current.value = void 0;
122
+ currentIndex.value = void 0;
123
+ }
124
+ function isImage(url) {
125
+ const ext = url.split(".").pop().split("?").shift() || "";
126
+ const allow = ["png", "jpeg", "jpg", "gif", "bmp", "webp"];
127
+ return allow.indexOf(ext.toLowerCase()) !== -1;
128
+ }
129
+ function dragover(e) {
130
+ if (!options.value.canReplace) {
131
+ return;
132
+ }
133
+ dragarea.value.style.opacity = "0.75";
134
+ }
135
+ function dragleave(e) {
136
+ if (!options.value.canReplace) {
137
+ return;
138
+ }
139
+ dragarea.value.style.opacity = "1";
140
+ }
141
+ function drop(event) {
142
+ if (!options.value.canReplace) {
143
+ return;
144
+ }
145
+ dragarea.value.style.opacity = "1";
146
+ const item = current.value;
147
+ const file = event.dataTransfer?.files[0] || null;
148
+ if (!file) {
149
+ return;
150
+ }
151
+ instance.value.checkFile(file);
152
+ if (instance.value.isReadonly) {
153
+ return;
154
+ }
155
+ item.file = file;
156
+ loading.value = true;
157
+ try {
158
+ instance.value.uploadFile(item);
159
+ } finally {
160
+ loading.value = false;
161
+ }
162
+ }
163
+ function uploading() {
164
+ useStack(props.stackName).push(true);
165
+ domEmit("uploading");
166
+ }
167
+ function uploaded() {
168
+ useStack(props.stackName).pop();
169
+ domEmit("uploaded");
170
+ }
171
+ function onChange(item) {
172
+ domEmit("change", item);
173
+ }
174
+ function domEmit(event, detail) {
175
+ el.dispatchEvent(new CustomEvent(event, { detail }));
176
+ }
177
+ const foo = ref();
178
+ foo.value = "Bar";
179
+ const icons = ref({
180
+ default: "fas fa-file",
181
+ pdf: "fas fa-file-pdf text-danger",
182
+ xls: "fas fa-file-excel text-success",
183
+ xlsx: "fas fa-file-excel text-success",
184
+ doc: "fas fa-file-word text-primary",
185
+ docx: "fas fa-file-word text-primary",
186
+ ppt: "fas fa-file-powerpoint text-warning",
187
+ pptx: "fas fa-file-powerpoint text-warning",
188
+ zip: "fas fa-file-archive text-dark",
189
+ "7z": "fas fa-file-archive text-dark",
190
+ rar: "fas fa-file-archive text-dark",
191
+ mp4: "fas fa-file-video text-dark",
192
+ avi: "fas fa-file-video text-dark",
193
+ flv: "fas fa-file-video text-dark",
194
+ mov: "fas fa-file-video text-dark",
195
+ ogg: "fas fa-file-video text-dark",
196
+ webm: "fas fa-file-video text-dark",
197
+ mpg: "fas fa-file-video text-dark",
198
+ mp3: "fas fa-file-audio text-dark",
199
+ acc: "fas fa-file-audio text-dark",
200
+ wav: "fas fa-file-audio text-dark"
201
+ });
202
+ function setIcons(newIcons, merge = true) {
203
+ if (merge) {
204
+ icons.value = { ...icons.value, ...newIcons };
205
+ return;
206
+ }
207
+ icons.value = newIcons;
208
+ }
209
+ expose({
210
+ uploader,
211
+ instance,
212
+ value,
213
+ canModify,
214
+ openFile,
215
+ itemClick,
216
+ isImage,
217
+ setIcons
218
+ });
219
+ function fileIcon(item) {
220
+ let path = item.file ? item.file.name : item.url;
221
+ path = String(path).split("?")[0];
222
+ const ext = path.split(".").pop() || "";
223
+ const def = "default" in icons ? icons.default : "fas fa-file";
224
+ return icons[String(ext || "default").toLowerCase()] || def;
225
+ }
226
+ return {
227
+ uploader,
228
+ uploadUrl,
229
+ value,
230
+ uploaderOptions,
231
+ draggableOptions,
232
+ modal,
233
+ dragarea,
234
+ options,
235
+ current,
236
+ currentIndex,
237
+ loading,
238
+ instance,
239
+ canModify,
240
+ openFile,
241
+ itemClick,
242
+ metaSave,
243
+ isImage,
244
+ dragover,
245
+ dragleave,
246
+ drop,
247
+ uploading,
248
+ uploaded,
249
+ onChange,
250
+ domEmit,
251
+ fileIcon
252
+ };
253
+ }
254
+ });
255
+ }
256
+ //# sourceMappingURL=field-multi-uploader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-multi-uploader.js","sources":["../../src/module/field-multi-uploader.ts"],"sourcesContent":["import { Modal } from 'bootstrap';\r\nimport type { Options } from 'sortablejs';\r\nimport {\r\n type ComponentPublicInstance,\r\n computed,\r\n createApp,\r\n defineComponent,\r\n getCurrentInstance,\r\n nextTick,\r\n onMounted,\r\n PropType,\r\n ref,\r\n useTemplateRef\r\n} from 'vue';\r\nimport { VueDraggable } from 'vue-draggable-plus';\r\nimport {\r\n createItem,\r\n ItemCard,\r\n ItemCardPlaceholder,\r\n MultiUploader,\r\n MultiUploaderComposableInstance,\r\n MultiUploaderOptions,\r\n UploaderItem\r\n} from 'vue-multi-uploader';\r\nimport css from 'vue-multi-uploader/src/vue-multi-uploader.scss?inline';\r\nimport { useStack } from '../composable';\r\nimport { data } from '../data';\r\nimport { forceArray, injectCssToDocument } from '../service';\r\nimport { mergeDeep } from '../utilities';\r\n\r\ninjectCssToDocument(css);\r\n\r\nexport type UniMultiUploaderOptions = {\r\n value?: any[];\r\n uploadUrl: string;\r\n maxFiles?: number;\r\n maxConcurrent?: number;\r\n thumbSize?: number;\r\n accept?: string;\r\n readonly: boolean;\r\n disabled: boolean;\r\n fieldName?: string;\r\n fieldFullName?: string;\r\n tmplSelector: string;\r\n canReplace: false;\r\n openFileHandler?: (item: UploaderItem) => void;\r\n}\r\n\r\nconst defaultOptions = {\r\n readonly: false,\r\n disabled: false,\r\n sortable: false,\r\n thumbSize: 150,\r\n maxConcurrent: 5,\r\n canReplace: false,\r\n tmplSelector: '#multi-uploader-field-tmpl',\r\n};\r\n\r\nclass MultiUploaderElement extends HTMLElement {\r\n static is = 'uni-multi-uploader';\r\n\r\n modalElement!: HTMLDivElement;\r\n vm!: ComponentPublicInstance;\r\n\r\n async connectedCallback() {\r\n let options: Partial<UniMultiUploaderOptions> = JSON.parse(\r\n this.getAttribute('options') || '{}'\r\n );\r\n\r\n const resolvedOptions: UniMultiUploaderOptions = mergeDeep({}, defaultOptions, options);\r\n\r\n // Make some default options since PHP will send NULL\r\n resolvedOptions.thumbSize ??= 150;\r\n\r\n this.modalElement = this.querySelector<HTMLDivElement>('.modal')!;\r\n\r\n const tmplSelector = resolvedOptions.tmplSelector;\r\n\r\n const app = createApp(\r\n createAppInstance(resolvedOptions, document.querySelector(tmplSelector)!.innerHTML, this)\r\n );\r\n\r\n this.vm = app.mount(this);\r\n }\r\n}\r\n\r\ncustomElements.define(MultiUploaderElement.is, MultiUploaderElement);\r\n\r\nfunction createAppInstance(opt: UniMultiUploaderOptions, tmpl: string, el: MultiUploaderElement) {\r\n return defineComponent({\r\n name: 'MultiUploaderFieldApp',\r\n template: tmpl,\r\n components: {\r\n VueDraggable,\r\n MultiUploader,\r\n ItemCard,\r\n ItemCardPlaceholder,\r\n },\r\n props: {\r\n stackName: String as PropType<string>,\r\n },\r\n setup(props, { expose }) {\r\n const options = ref<UniMultiUploaderOptions>(opt);\r\n const current = ref<UploaderItem>();\r\n const currentIndex = ref<number>();\r\n const loading = ref(false);\r\n const dragarea = ref<HTMLDivElement>();\r\n const modal = ref<HTMLDivElement>();\r\n const app = getCurrentInstance();\r\n const uploader = useTemplateRef<typeof MultiUploader>('uploader');\r\n const canModify = computed(() => !options.value.disabled && !options.value.readonly);\r\n const instance = ref<MultiUploaderComposableInstance>();\r\n\r\n onMounted(() => {\r\n instance.value = uploader.value!.instance;\r\n\r\n domEmit('multi-uploader:mounted', { app, uploader });\r\n });\r\n\r\n const items = ref<UploaderItem[]>([]);\r\n\r\n for (let item of forceArray(options.value.value)) {\r\n if (typeof item === 'string') {\r\n item = {\r\n url: item\r\n };\r\n }\r\n\r\n const uploadItem = createItem({\r\n url: item.url || '',\r\n thumbUrl: item.thumbUrl || item.thumb_url || item.url || '',\r\n data: item\r\n });\r\n\r\n items.value.push(uploadItem);\r\n }\r\n\r\n const uploadUrl = options.value.uploadUrl;\r\n const value = items.value;\r\n const uploaderOptions = ref<MultiUploaderOptions>({\r\n maxFiles: () => options.value.maxFiles,\r\n readonly: () => options.value.readonly,\r\n disabled: () => options.value.disabled,\r\n accept: () => options.value.accept,\r\n maxConcurrent: () => options.value.maxConcurrent,\r\n prepareXhr(xhr) {\r\n xhr.setRequestHeader(\r\n 'X-CSRF-TOKEN',\r\n data('csrf-token')\r\n );\r\n },\r\n onItemUploadSuccess(item, xhr) {\r\n const res = JSON.parse(xhr.responseText);\r\n item.url = res.data.url;\r\n item.thumbUrl = res.data.thumbUrl || res.data.thumb_url || res.data.url;\r\n item.data = res.data;\r\n item.data.title ??= item.url.split('/').pop()?.split('?').shift() || '';\r\n }\r\n });\r\n const draggableOptions: Options = {\r\n draggable: '.c-drag-item',\r\n animation: 300,\r\n disabled: !canModify.value,\r\n };\r\n\r\n function openFile(item: UploaderItem) {\r\n if (options.value.openFileHandler) {\r\n options.value.openFileHandler(item);\r\n } else {\r\n window.open(item.download_url || item.url);\r\n }\r\n }\r\n\r\n async function itemClick(item: UploaderItem, i: number, event: MouseEvent) {\r\n current.value = item;\r\n currentIndex.value = i;\r\n\r\n domEmit('item-click', { item, i });\r\n\r\n nextTick().then(() => {\r\n Modal.getOrCreateInstance(modal.value!).show();\r\n });\r\n // this.$options.metaModal.modal('show');\r\n }\r\n\r\n function metaSave() {\r\n current.value = undefined;\r\n currentIndex.value = undefined;\r\n\r\n // nextTick().then(() => {\r\n // new bootstrap.Modal(modal.value).hide();\r\n // });\r\n // this.$options.metaModal.modal('hide');\r\n }\r\n\r\n function isImage(url: string) {\r\n const ext = url.split('.').pop()!.split('?').shift() || '';\r\n const allow = ['png', 'jpeg', 'jpg', 'gif', 'bmp', 'webp'];\r\n\r\n return allow.indexOf(ext.toLowerCase()) !== -1;\r\n }\r\n\r\n function dragover(e: DragEvent) {\r\n if (!options.value.canReplace) {\r\n return;\r\n }\r\n\r\n dragarea.value!.style.opacity = '0.75';\r\n }\r\n\r\n function dragleave(e: DragEvent) {\r\n if (!options.value.canReplace) {\r\n return;\r\n }\r\n\r\n dragarea.value!.style.opacity = '1';\r\n }\r\n\r\n function drop(event: DragEvent) {\r\n if (!options.value.canReplace) {\r\n return;\r\n }\r\n\r\n dragarea.value!.style.opacity = '1';\r\n const item = current.value;\r\n const file = event.dataTransfer?.files[0] || null;\r\n\r\n if (!file) {\r\n return;\r\n }\r\n\r\n instance.value!.checkFile(file);\r\n\r\n if (instance.value!.isReadonly) {\r\n return;\r\n }\r\n\r\n item!.file = file;\r\n\r\n loading.value = true;\r\n\r\n try {\r\n instance.value!.uploadFile(item!);\r\n } finally {\r\n loading.value = false;\r\n }\r\n }\r\n\r\n function uploading() {\r\n useStack(props.stackName).push(true);\r\n\r\n domEmit('uploading');\r\n }\r\n\r\n function uploaded() {\r\n useStack(props.stackName).pop();\r\n\r\n domEmit('uploaded');\r\n }\r\n\r\n function onChange(item: UploaderItem) {\r\n domEmit('change', item);\r\n }\r\n\r\n function domEmit(event: string, detail?: any) {\r\n el.dispatchEvent(new CustomEvent(event, { detail }));\r\n }\r\n\r\n const foo = ref<string>();\r\n\r\n foo.value = 'Bar';\r\n\r\n const icons = ref<Record<string, string>>({\r\n default: 'fas fa-file',\r\n pdf: 'fas fa-file-pdf text-danger',\r\n xls: 'fas fa-file-excel text-success',\r\n xlsx: 'fas fa-file-excel text-success',\r\n doc: 'fas fa-file-word text-primary',\r\n docx: 'fas fa-file-word text-primary',\r\n ppt: 'fas fa-file-powerpoint text-warning',\r\n pptx: 'fas fa-file-powerpoint text-warning',\r\n zip: 'fas fa-file-archive text-dark',\r\n '7z': 'fas fa-file-archive text-dark',\r\n rar: 'fas fa-file-archive text-dark',\r\n mp4: 'fas fa-file-video text-dark',\r\n avi: 'fas fa-file-video text-dark',\r\n flv: 'fas fa-file-video text-dark',\r\n mov: 'fas fa-file-video text-dark',\r\n ogg: 'fas fa-file-video text-dark',\r\n webm: 'fas fa-file-video text-dark',\r\n mpg: 'fas fa-file-video text-dark',\r\n mp3: 'fas fa-file-audio text-dark',\r\n acc: 'fas fa-file-audio text-dark',\r\n wav: 'fas fa-file-audio text-dark',\r\n });\r\n\r\n function setIcons(newIcons: Record<string, string>, merge = true) {\r\n if (merge) {\r\n icons.value = { ...icons.value, ...newIcons };\r\n return;\r\n }\r\n\r\n icons.value = newIcons;\r\n }\r\n\r\n expose({\r\n uploader,\r\n instance,\r\n value,\r\n canModify,\r\n openFile,\r\n itemClick,\r\n isImage,\r\n setIcons,\r\n });\r\n\r\n function fileIcon(item: UploaderItem) {\r\n let path = item.file ? item.file.name : item.url;\r\n\r\n // strip query\r\n path = String(path).split('?')[0];\r\n\r\n // Get extension\r\n const ext = path.split('.').pop() || '';\r\n\r\n const def = 'default' in icons ? icons.default : 'fas fa-file';\r\n\r\n return icons[String(ext || 'default').toLowerCase() as keyof typeof icons] || def;\r\n }\r\n\r\n return {\r\n uploader,\r\n uploadUrl,\r\n value,\r\n uploaderOptions,\r\n draggableOptions,\r\n modal,\r\n dragarea,\r\n options,\r\n current,\r\n currentIndex,\r\n loading,\r\n instance,\r\n canModify,\r\n\r\n openFile,\r\n itemClick,\r\n metaSave,\r\n isImage,\r\n dragover,\r\n dragleave,\r\n drop,\r\n uploading,\r\n uploaded,\r\n onChange,\r\n domEmit,\r\n fileIcon,\r\n };\r\n }\r\n });\r\n}\r\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,132 @@
1
+ import { c as cloneDeep } from "./cloneDeep.js";
2
+ import { a4 as prepareAlpineDefer, a9 as useCssImport, a5 as mergeDeep, f as initAlpineComponent, K as uid } from "./unicorn.js";
3
+ const defaultOptions = {
4
+ id: "",
5
+ fieldName: "",
6
+ sortable: false,
7
+ hasKey: false,
8
+ singleArray: false,
9
+ ensureFirstRow: false,
10
+ max: null
11
+ };
12
+ function prepareItem(item) {
13
+ if (item.uid == null) {
14
+ item.uid = uid();
15
+ }
16
+ return item;
17
+ }
18
+ async function init() {
19
+ await prepareAlpineDefer(async (Alpine) => {
20
+ useCssImport("@vue-animate");
21
+ Alpine.data("RepeatableField", ({ items, defaultValues, attrs }, options) => ({
22
+ items,
23
+ defaultValues,
24
+ attrs,
25
+ options: mergeDeep(defaultOptions, options),
26
+ init() {
27
+ if (this.options.sortable) {
28
+ import("sortablejs").then(({ default: Sortable }) => {
29
+ Sortable.create(this.$refs.tbody, {
30
+ handle: ".h-handle",
31
+ animation: 300,
32
+ onEnd: (event) => {
33
+ const items2 = Alpine.raw(this.items);
34
+ const droppedAtItem = items2.splice(event.oldIndex, 1)[0];
35
+ items2.splice(event.newIndex, 0, droppedAtItem);
36
+ this.items = items2;
37
+ let keys = [];
38
+ for (let item of items2) {
39
+ keys.push(item.uid);
40
+ }
41
+ this.$refs.steps_template._x_prevKeys = keys;
42
+ const elements = this.$refs.steps_template.parentElement.querySelectorAll("tr");
43
+ [].slice.call(elements).forEach((ele, i) => {
44
+ if (ele?._x_dataStack[0]?.i != null) {
45
+ ele._x_dataStack[0].i = i;
46
+ }
47
+ });
48
+ }
49
+ });
50
+ });
51
+ }
52
+ this.items.forEach(prepareItem);
53
+ if (this.options.ensureFirstRow) {
54
+ this.ensureFirstRow();
55
+ }
56
+ },
57
+ addItem(i) {
58
+ const item = prepareItem(this.getEmptyItem());
59
+ this.items.splice(i + 1, 0, item);
60
+ },
61
+ delItem(i) {
62
+ const el = this.getItemElementByUID(this.items[i].uid);
63
+ let hasAnimate = false;
64
+ el?.addEventListener("animationstart", () => {
65
+ hasAnimate = true;
66
+ }, { once: true });
67
+ el?.classList.add("animate__fadeOut");
68
+ setTimeout(() => {
69
+ if (!hasAnimate) {
70
+ this._removeItem(i);
71
+ }
72
+ }, 100);
73
+ el?.addEventListener("animationend", () => {
74
+ this._removeItem(i);
75
+ }, { once: true });
76
+ },
77
+ _removeItem(i) {
78
+ this.items.splice(i, 1);
79
+ if (this.options.ensureFirstRow) {
80
+ this.ensureFirstRow();
81
+ }
82
+ },
83
+ ensureFirstRow() {
84
+ if (this.items.length === 0) {
85
+ this.items.push(prepareItem(this.getEmptyItem()));
86
+ }
87
+ },
88
+ getItemElementByUID(uid2) {
89
+ return this.$root.querySelector(`[data-item="${uid2}"]`);
90
+ },
91
+ getId(i, item, field) {
92
+ return `${this.id}-${item.uid}-${field}`;
93
+ },
94
+ getName(i, item, field) {
95
+ if (this.options.singleArray) {
96
+ if (this.options.hasKey) {
97
+ if (field === "key") {
98
+ return "";
99
+ }
100
+ return `${this.fieldName}[${item.key}]`;
101
+ }
102
+ return `${this.fieldName}[]`;
103
+ }
104
+ return `${this.fieldName}[${i}][${field}]`;
105
+ },
106
+ getEmptyItem() {
107
+ return cloneDeep(this.defaultValues);
108
+ },
109
+ get canAdd() {
110
+ if (!this.options.max) {
111
+ return true;
112
+ }
113
+ return this.options.max > this.items.length;
114
+ },
115
+ get canModify() {
116
+ return this.attrs.disabled == null && this.attrs.readonly == null;
117
+ },
118
+ get fieldName() {
119
+ return this.options.fieldName;
120
+ },
121
+ get id() {
122
+ return this.options.id;
123
+ }
124
+ }));
125
+ });
126
+ await initAlpineComponent("data-repeatable");
127
+ }
128
+ const ready = /* @__PURE__ */ init();
129
+ export {
130
+ ready
131
+ };
132
+ //# sourceMappingURL=field-repeatable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-repeatable.js","sources":["../../src/module/field-repeatable.ts"],"sourcesContent":["import { cloneDeep } from 'lodash-es';\r\nimport { initAlpineComponent, prepareAlpineDefer, uid, useCssImport } from '../service';\r\nimport { mergeDeep } from '../utilities';\r\n\r\nexport interface RepeatableOptions {\r\n id?: string;\r\n fieldName?: string;\r\n sortable?: boolean;\r\n hasKey?: boolean;\r\n singleArray?: boolean;\r\n ensureFirstRow?: boolean;\r\n max?: number | null;\r\n}\r\n\r\nconst defaultOptions: RepeatableOptions = {\r\n id: '',\r\n fieldName: '',\r\n sortable: false,\r\n hasKey: false,\r\n singleArray: false,\r\n ensureFirstRow: false,\r\n max: null,\r\n};\r\n\r\nfunction prepareItem(item: any) {\r\n if (item.uid == null) {\r\n item.uid = uid();\r\n }\r\n return item;\r\n}\r\n\r\ntype RepeatableParams = {\r\n items: Record<string, any>[];\r\n defaultValues: any;\r\n attrs: Record<string, any>;\r\n};\r\n\r\nasync function init() {\r\n await prepareAlpineDefer(async (Alpine) => {\r\n useCssImport('@vue-animate');\r\n\r\n Alpine.data('RepeatableField', ({ items, defaultValues, attrs }: RepeatableParams, options: RepeatableOptions) => ({\r\n items,\r\n defaultValues,\r\n attrs,\r\n options: mergeDeep<RepeatableOptions>(defaultOptions, options),\r\n init() {\r\n // this.items = this.items.filter((item) => item !== '__EMPTY_ARRAY__');\r\n\r\n if (this.options.sortable) {\r\n // @see https://github.com/alpinejs/alpine/discussions/1635\r\n import('sortablejs').then(({ default: Sortable }) => {\r\n Sortable.create(this.$refs.tbody, {\r\n handle: '.h-handle',\r\n animation: 300,\r\n onEnd: (event: any) => {\r\n // V3 helper to unwrap the proxy\r\n const items = Alpine.raw(this.items);\r\n\r\n // splice mutates the original object, which\r\n // you want to avoid. In this case it works because we\r\n // created a temporary object that we can control\r\n // That way we know there are no side effects\r\n const droppedAtItem = items.splice(event.oldIndex, 1)[0];\r\n items.splice(event.newIndex, 0, droppedAtItem);\r\n //\r\n // // Alpine will update when you modify the state,\r\n // // so we need to set it back to our new state\r\n this.items = items;\r\n\r\n // HACK update prevKeys to new sort order\r\n let keys = [];\r\n for (let item of items) {\r\n keys.push(item.uid);\r\n }\r\n\r\n // HACK update index of dataStack\r\n // @ts-ignore\r\n this.$refs.steps_template._x_prevKeys = keys;\r\n // @ts-ignore\r\n const elements = this.$refs.steps_template\r\n .parentElement\r\n .querySelectorAll('tr');\r\n\r\n [].slice.call(elements).forEach((ele, i) => {\r\n // @ts-ignore\r\n if (ele?._x_dataStack[0]?.i != null) {\r\n // @ts-ignore\r\n ele._x_dataStack[0].i = i;\r\n }\r\n });\r\n }\r\n });\r\n });\r\n }\r\n\r\n this.items.forEach(prepareItem);\r\n\r\n if (this.options.ensureFirstRow) {\r\n this.ensureFirstRow();\r\n }\r\n },\r\n\r\n addItem(i: number) {\r\n const item = prepareItem(this.getEmptyItem());\r\n\r\n this.items.splice(i + 1, 0, item);\r\n },\r\n\r\n delItem(i: number) {\r\n const el = this.getItemElementByUID(this.items[i].uid);\r\n let hasAnimate = false;\r\n\r\n el?.addEventListener('animationstart', () => {\r\n hasAnimate = true;\r\n }, { once: true });\r\n\r\n el?.classList.add('animate__fadeOut');\r\n\r\n setTimeout(() => {\r\n if (!hasAnimate) {\r\n this._removeItem(i);\r\n }\r\n }, 100);\r\n\r\n el?.addEventListener('animationend', () => {\r\n this._removeItem(i);\r\n }, { once: true });\r\n },\r\n\r\n _removeItem(i: number) {\r\n this.items.splice(i, 1);\r\n\r\n if (this.options.ensureFirstRow) {\r\n this.ensureFirstRow();\r\n }\r\n },\r\n\r\n ensureFirstRow() {\r\n if (this.items.length === 0) {\r\n this.items.push(prepareItem(this.getEmptyItem()));\r\n }\r\n },\r\n\r\n getItemElementByUID(uid: string) {\r\n return this.$root.querySelector(`[data-item=\"${uid}\"]`);\r\n },\r\n\r\n getId(i: number, item: any, field: string) {\r\n return `${this.id}-${item.uid}-${field}`;\r\n },\r\n\r\n getName(i: number, item: any, field: string) {\r\n if (this.options.singleArray) {\r\n if (this.options.hasKey) {\r\n if (field === 'key') {\r\n return '';\r\n }\r\n\r\n return `${this.fieldName}[${item.key}]`;\r\n }\r\n\r\n return `${this.fieldName}[]`;\r\n }\r\n\r\n return `${this.fieldName}[${i}][${field}]`;\r\n },\r\n\r\n getEmptyItem() {\r\n return cloneDeep(this.defaultValues);\r\n },\r\n\r\n get canAdd() {\r\n if (!this.options.max) {\r\n return true;\r\n }\r\n\r\n return this.options.max > this.items.length;\r\n },\r\n\r\n get canModify() {\r\n return this.attrs.disabled == null && this.attrs.readonly == null;\r\n },\r\n\r\n get fieldName() {\r\n return this.options.fieldName;\r\n },\r\n\r\n get id() {\r\n return this.options.id;\r\n }\r\n }));\r\n });\r\n\r\n await initAlpineComponent('data-repeatable');\r\n}\r\n\r\nexport const ready = init();\r\n\r\nexport interface RepeatableModule {\r\n ready: typeof ready;\r\n}\r\n"],"names":["items","uid"],"mappings":"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"}