mirror of
				https://github.com/Fabio286/antares.git
				synced 2025-06-05 21:59:22 +02:00 
			
		
		
		
	refactor: ts and composition api for base components
This commit is contained in:
		| @@ -46,70 +46,57 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script lang="ts"> | ||||
| import { computed, defineComponent, onBeforeUnmount } from 'vue'; | ||||
| <script setup lang="ts"> | ||||
| import { computed, onBeforeUnmount, PropType, useSlots } from 'vue'; | ||||
|  | ||||
| export default defineComponent({ | ||||
|    name: 'BaseConfirmModal', | ||||
|    props: { | ||||
|       size: { | ||||
|          type: String, | ||||
|          validator: (prop: string) => ['small', 'medium', '400', 'large'].includes(prop), | ||||
|          default: 'small' | ||||
|       }, | ||||
|       hideFooter: { | ||||
|          type: Boolean, | ||||
|          default: false | ||||
|       }, | ||||
|       confirmText: String, | ||||
|       cancelText: String | ||||
| const props = defineProps({ | ||||
|    size: { | ||||
|       type: String as PropType<'small' | 'medium' | '400' | 'large'>, | ||||
|       validator: (prop: string) => ['small', 'medium', '400', 'large'].includes(prop), | ||||
|       default: 'small' | ||||
|    }, | ||||
|    emits: ['confirm', 'hide'], | ||||
|    setup (props, { slots, emit }) { | ||||
|       const hasHeader = computed(() => !!slots.header); | ||||
|       const hasBody = computed(() => !!slots.body); | ||||
|       const hasDefault = computed(() => !!slots.default); | ||||
|       const modalSizeClass = computed(() => { | ||||
|          if (props.size === 'small') | ||||
|             return 'modal-sm'; | ||||
|          if (props.size === '400') | ||||
|             return 'modal-400'; | ||||
|          else if (props.size === 'large') | ||||
|             return 'modal-lg'; | ||||
|          else return ''; | ||||
|       }); | ||||
|    hideFooter: { | ||||
|       type: Boolean, | ||||
|       default: false | ||||
|    }, | ||||
|    confirmText: String, | ||||
|    cancelText: String | ||||
| }); | ||||
| const emit = defineEmits(['confirm', 'hide']); | ||||
| const slots = useSlots(); | ||||
|  | ||||
|       const confirmModal = () => { | ||||
|          emit('confirm'); | ||||
|          hideModal(); | ||||
|       }; | ||||
| const hasHeader = computed(() => !!slots.header); | ||||
| const hasBody = computed(() => !!slots.body); | ||||
| const hasDefault = computed(() => !!slots.default); | ||||
| const modalSizeClass = computed(() => { | ||||
|    if (props.size === 'small') | ||||
|       return 'modal-sm'; | ||||
|    if (props.size === '400') | ||||
|       return 'modal-400'; | ||||
|    else if (props.size === 'large') | ||||
|       return 'modal-lg'; | ||||
|    else return ''; | ||||
| }); | ||||
|  | ||||
|       const hideModal = () => { | ||||
|          emit('hide'); | ||||
|       }; | ||||
| const confirmModal = () => { | ||||
|    emit('confirm'); | ||||
|    hideModal(); | ||||
| }; | ||||
|  | ||||
|       const onKey = (e: KeyboardEvent) => { | ||||
|          e.stopPropagation(); | ||||
|          if (e.key === 'Escape') | ||||
|             hideModal(); | ||||
|       }; | ||||
| const hideModal = () => { | ||||
|    emit('hide'); | ||||
| }; | ||||
|  | ||||
|       window.addEventListener('keydown', onKey); | ||||
| const onKey = (e: KeyboardEvent) => { | ||||
|    e.stopPropagation(); | ||||
|    if (e.key === 'Escape') | ||||
|       hideModal(); | ||||
| }; | ||||
|  | ||||
|       onBeforeUnmount(() => { | ||||
|          window.removeEventListener('keydown', onKey); | ||||
|       }); | ||||
| window.addEventListener('keydown', onKey); | ||||
|  | ||||
|       return { | ||||
|          hasHeader, | ||||
|          hasBody, | ||||
|          hasDefault, | ||||
|          modalSizeClass, | ||||
|          confirmModal, | ||||
|          hideModal, | ||||
|          onKey | ||||
|       }; | ||||
|    } | ||||
| onBeforeUnmount(() => { | ||||
|    window.removeEventListener('keydown', onKey); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -15,67 +15,60 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|    name: 'BaseContextMenu', | ||||
|    props: { | ||||
|       contextEvent: MouseEvent | ||||
|    }, | ||||
|    emits: ['close-context'], | ||||
|    data () { | ||||
|       return { | ||||
|          contextSize: null, | ||||
|          isBottom: false | ||||
|       }; | ||||
|    }, | ||||
|    computed: { | ||||
|       position () { | ||||
|          let topCord = 0; | ||||
|          let leftCord = 0; | ||||
| <script setup lang="ts"> | ||||
| import { computed, onBeforeUnmount, onMounted, Ref, ref } from 'vue'; | ||||
|  | ||||
|          if (this.contextEvent) { | ||||
|             const { clientY, clientX } = this.contextEvent; | ||||
|             topCord = `${clientY + 2}px`; | ||||
|             leftCord = `${clientX + 5}px`; | ||||
| const contextContent: Ref<HTMLDivElement> = ref(null); | ||||
| const contextSize: Ref<DOMRect> = ref(null); | ||||
| const isBottom: Ref<boolean> = ref(false); | ||||
| const props = defineProps<{contextEvent: MouseEvent}>(); | ||||
| const emit = defineEmits(['close-context']); | ||||
|  | ||||
|             if (this.contextSize) { | ||||
|                if (clientY + (this.contextSize.height < 200 ? 200 : this.contextSize.height) + 5 >= window.innerHeight) { | ||||
|                   topCord = `${clientY + 3 - this.contextSize.height}px`; | ||||
|                   this.isBottom = true; | ||||
|                } | ||||
| const position = computed(() => { | ||||
|    let topCord = '0px'; | ||||
|    let leftCord = '0px'; | ||||
|  | ||||
|                if (clientX + this.contextSize.width + 5 >= window.innerWidth) | ||||
|                   leftCord = `${clientX - this.contextSize.width}px`; | ||||
|             } | ||||
|    if (props.contextEvent) { | ||||
|       const { clientY, clientX } = props.contextEvent; | ||||
|       topCord = `${clientY + 2}px`; | ||||
|       leftCord = `${clientX + 5}px`; | ||||
|  | ||||
|       if (contextSize.value) { | ||||
|          if (clientY + (contextSize.value.height < 200 ? 200 : contextSize.value.height) + 5 >= window.innerHeight) { | ||||
|             topCord = `${clientY + 3 - contextSize.value.height}px`; | ||||
|             isBottom.value = true; | ||||
|          } | ||||
|  | ||||
|          return { | ||||
|             top: topCord, | ||||
|             left: leftCord | ||||
|          }; | ||||
|       } | ||||
|    }, | ||||
|    created () { | ||||
|       window.addEventListener('keydown', this.onKey); | ||||
|    }, | ||||
|    mounted () { | ||||
|       if (this.$refs.contextContent) | ||||
|          this.contextSize = this.$refs.contextContent.getBoundingClientRect(); | ||||
|    }, | ||||
|    beforeUnmount () { | ||||
|       window.removeEventListener('keydown', this.onKey); | ||||
|    }, | ||||
|    methods: { | ||||
|       close () { | ||||
|          this.$emit('close-context'); | ||||
|       }, | ||||
|       onKey (e) { | ||||
|          e.stopPropagation(); | ||||
|          if (e.key === 'Escape') | ||||
|             this.close(); | ||||
|          if (clientX + contextSize.value.width + 5 >= window.innerWidth) | ||||
|             leftCord = `${clientX - contextSize.value.width}px`; | ||||
|       } | ||||
|    } | ||||
|  | ||||
|    return { | ||||
|       top: topCord, | ||||
|       left: leftCord | ||||
|    }; | ||||
| }); | ||||
|  | ||||
| const close = () => { | ||||
|    emit('close-context'); | ||||
| }; | ||||
| const onKey = (e: KeyboardEvent) => { | ||||
|    e.stopPropagation(); | ||||
|    if (e.key === 'Escape') | ||||
|       close(); | ||||
| }; | ||||
|  | ||||
| window.addEventListener('keydown', onKey); | ||||
|  | ||||
| onMounted(() => { | ||||
|    if (contextContent.value) | ||||
|       contextSize.value = contextContent.value.getBoundingClientRect(); | ||||
| }); | ||||
|  | ||||
| onBeforeUnmount(() => { | ||||
|    window.removeEventListener('keydown', onKey); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   | ||||
| @@ -4,11 +4,6 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|    name: 'BaseLoader' | ||||
| }; | ||||
| </script> | ||||
| <style scoped> | ||||
| .empty { | ||||
|   position: absolute; | ||||
|   | ||||
| @@ -1,95 +1,93 @@ | ||||
| <template> | ||||
|    <div id="map" class="map" /> | ||||
| </template> | ||||
| <script> | ||||
| import L from 'leaflet'; | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import { onMounted, PropType, Ref, ref } from 'vue'; | ||||
| import * as L from 'leaflet'; | ||||
| import { | ||||
|    point, | ||||
|    lineString, | ||||
|    polygon | ||||
| } from '@turf/helpers'; | ||||
| import { GeoJsonObject } from 'geojson'; | ||||
| import { getArrayDepth } from 'common/libs/getArrayDepth'; | ||||
|  | ||||
| export default { | ||||
|    name: 'BaseMap', | ||||
|    props: { | ||||
|       points: [Object, Array], | ||||
|       isMultiSpatial: Boolean | ||||
|    }, | ||||
|    data () { | ||||
|       return { | ||||
|          map: null, | ||||
|          markers: [], | ||||
|          center: null | ||||
|       }; | ||||
|    }, | ||||
|    mounted () { | ||||
|       if (this.isMultiSpatial) { | ||||
|          for (const element of this.points) | ||||
|             this.markers.push(this.getMarkers(element)); | ||||
|       } | ||||
|       else { | ||||
|          this.markers = this.getMarkers(this.points); | ||||
| interface Coordinates { x: number; y: number } | ||||
|  | ||||
|          if (!Array.isArray(this.points)) | ||||
|             this.center = [this.points.y, this.points.x]; | ||||
|       } | ||||
| const props = defineProps({ | ||||
|    points: [Object, Array] as PropType<Coordinates | Coordinates[]>, | ||||
|    isMultiSpatial: Boolean | ||||
| }); | ||||
| const map: Ref<L.Map> = ref(null); | ||||
| const markers: Ref<GeoJsonObject | GeoJsonObject[]> = ref(null); | ||||
| const center: Ref<[number, number]> = ref(null); | ||||
|  | ||||
|       this.map = L.map('map', { | ||||
|          center: this.center || [0, 0], | ||||
|          zoom: 15, | ||||
|          minZoom: 1, | ||||
|          attributionControl: false | ||||
|       }); | ||||
|  | ||||
|       L.control.attribution({ prefix: '<b>Leaflet</b>' }).addTo(this.map); | ||||
|  | ||||
|       const geoJsonObj = L.geoJSON(this.markers, { | ||||
|          style: function () { | ||||
|             return { | ||||
|                weight: 2, | ||||
|                fillColor: '#ff7800', | ||||
|                color: '#ff7800', | ||||
|                opacity: 0.8, | ||||
|                fillOpacity: 0.4 | ||||
|             }; | ||||
|          }, | ||||
|          pointToLayer: function (feature, latlng) { | ||||
|             return L.circleMarker(latlng, { | ||||
|                radius: 7, | ||||
|                weight: 2, | ||||
|                fillColor: '#ff7800', | ||||
|                color: '#ff7800', | ||||
|                opacity: 0.8, | ||||
|                fillOpacity: 0.4 | ||||
|             }); | ||||
|          } | ||||
|       }).addTo(this.map); | ||||
|  | ||||
|       const southWest = L.latLng(-90, -180); | ||||
|       const northEast = L.latLng(90, 180); | ||||
|       const bounds = L.latLngBounds(southWest, northEast); | ||||
|       this.map.setMaxBounds(bounds); | ||||
|  | ||||
|       if (!this.center) this.map.fitBounds(geoJsonObj.getBounds()); | ||||
|  | ||||
|       L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | ||||
|          attribution: '© <b>OpenStreetMap</b>' | ||||
|       }).addTo(this.map); | ||||
|    }, | ||||
|    methods: { | ||||
|       getMarkers (points) { | ||||
|          if (Array.isArray(points)) { | ||||
|             if (getArrayDepth(points) === 1) | ||||
|                return lineString(points.reduce((acc, curr) => [...acc, [curr.x, curr.y]], [])); | ||||
|             else | ||||
|                return polygon(points.map(arr => arr.reduce((acc, curr) => [...acc, [curr.x, curr.y]], []))); | ||||
|          } | ||||
|          else | ||||
|             return point([points.x, points.y]); | ||||
|       } | ||||
| const getMarkers = (points: Coordinates) => { | ||||
|    if (Array.isArray(points)) { | ||||
|       if (getArrayDepth(points) === 1) | ||||
|          return lineString(points.reduce((acc, curr) => [...acc, [curr.x, curr.y]], [])); | ||||
|       else | ||||
|          return polygon(points.map(arr => arr.reduce((acc: Coordinates[], curr: Coordinates) => [...acc, [curr.x, curr.y]], []))); | ||||
|    } | ||||
|    else | ||||
|       return point([points.x, points.y]); | ||||
| }; | ||||
|  | ||||
| onMounted(() => { | ||||
|    if (props.isMultiSpatial) { | ||||
|       for (const element of props.points as Coordinates[]) | ||||
|          (markers.value as GeoJsonObject[]).push(getMarkers(element)); | ||||
|    } | ||||
|    else { | ||||
|       markers.value = getMarkers(props.points as Coordinates); | ||||
|  | ||||
|       if (!Array.isArray(props.points)) | ||||
|          center.value = [props.points.y, props.points.x]; | ||||
|    } | ||||
|  | ||||
|    map.value = L.map('map', { | ||||
|       center: center.value || [0, 0], | ||||
|       zoom: 15, | ||||
|       minZoom: 1, | ||||
|       attributionControl: false | ||||
|    }); | ||||
|  | ||||
|    L.control.attribution({ prefix: '<b>Leaflet</b>' }).addTo(map.value); | ||||
|  | ||||
|    const geoJsonObj = L.geoJSON((markers.value as GeoJsonObject), { | ||||
|       style: function () { | ||||
|          return { | ||||
|             weight: 2, | ||||
|             fillColor: '#ff7800', | ||||
|             color: '#ff7800', | ||||
|             opacity: 0.8, | ||||
|             fillOpacity: 0.4 | ||||
|          }; | ||||
|       }, | ||||
|       pointToLayer: function (feature, latlng) { | ||||
|          return L.circleMarker(latlng, { | ||||
|             radius: 7, | ||||
|             weight: 2, | ||||
|             fillColor: '#ff7800', | ||||
|             color: '#ff7800', | ||||
|             opacity: 0.8, | ||||
|             fillOpacity: 0.4 | ||||
|          }); | ||||
|       } | ||||
|    }).addTo(map.value); | ||||
|  | ||||
|    const southWest = L.latLng(-90, -180); | ||||
|    const northEast = L.latLng(90, 180); | ||||
|    const bounds = L.latLngBounds(southWest, northEast); | ||||
|    map.value.setMaxBounds(bounds); | ||||
|  | ||||
|    if (!center.value) map.value.fitBounds(geoJsonObj.getBounds()); | ||||
|  | ||||
|    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { | ||||
|       attribution: '© <b>OpenStreetMap</b>' | ||||
|    }).addTo(map.value); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style lang="scss"> | ||||
|   | ||||
| @@ -14,64 +14,58 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|    name: 'BaseNotification', | ||||
|    props: { | ||||
|       message: { | ||||
|          type: String, | ||||
|          default: '' | ||||
|       }, | ||||
|       status: { | ||||
|          type: String, | ||||
|          default: '' | ||||
|       } | ||||
|    }, | ||||
|    emits: ['close'], | ||||
|    data () { | ||||
|       return { | ||||
|          isExpanded: false | ||||
|       }; | ||||
|    }, | ||||
|    computed: { | ||||
|       notificationStatus () { | ||||
|          let className = ''; | ||||
|          let iconName = ''; | ||||
|          switch (this.status) { | ||||
|             case 'success': | ||||
|                className = 'toast-success'; | ||||
|                iconName = 'mdi-check'; | ||||
|                break; | ||||
|             case 'error': | ||||
|                className = 'toast-error'; | ||||
|                iconName = 'mdi-alert-rhombus'; | ||||
|                break; | ||||
|             case 'warning': | ||||
|                className = 'toast-warning'; | ||||
|                iconName = 'mdi-alert'; | ||||
|                break; | ||||
|             case 'primary': | ||||
|                className = 'toast-primary'; | ||||
|                iconName = 'mdi-information-outline'; | ||||
|                break; | ||||
|          } | ||||
| <script setup lang="ts"> | ||||
| import { computed, ref } from 'vue'; | ||||
|  | ||||
|          return { className, iconName }; | ||||
|       }, | ||||
|       isExpandable () { | ||||
|          return this.message.length > 80; | ||||
|       } | ||||
| const props = defineProps({ | ||||
|    message: { | ||||
|       type: String, | ||||
|       default: '' | ||||
|    }, | ||||
|    methods: { | ||||
|       hideToast () { | ||||
|          this.$emit('close'); | ||||
|       }, | ||||
|       toggleExpand () { | ||||
|          this.isExpanded = !this.isExpanded; | ||||
|       } | ||||
|    status: { | ||||
|       type: String, | ||||
|       default: '' | ||||
|    } | ||||
| }); | ||||
| const isExpanded = ref(false); | ||||
| const emit = defineEmits(['close']); | ||||
|  | ||||
| const notificationStatus = computed(() => { | ||||
|    let className = ''; | ||||
|    let iconName = ''; | ||||
|    switch (props.status) { | ||||
|       case 'success': | ||||
|          className = 'toast-success'; | ||||
|          iconName = 'mdi-check'; | ||||
|          break; | ||||
|       case 'error': | ||||
|          className = 'toast-error'; | ||||
|          iconName = 'mdi-alert-rhombus'; | ||||
|          break; | ||||
|       case 'warning': | ||||
|          className = 'toast-warning'; | ||||
|          iconName = 'mdi-alert'; | ||||
|          break; | ||||
|       case 'primary': | ||||
|          className = 'toast-primary'; | ||||
|          iconName = 'mdi-information-outline'; | ||||
|          break; | ||||
|    } | ||||
|  | ||||
|    return { className, iconName }; | ||||
| }); | ||||
|  | ||||
| const isExpandable = computed(() => props.message.length > 80); | ||||
|  | ||||
| const hideToast = () => { | ||||
|    emit('close'); | ||||
| }; | ||||
|  | ||||
| const toggleExpand = () => { | ||||
|    isExpanded.value = !isExpanded.value; | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
|   .toast { | ||||
|     display: flex; | ||||
|   | ||||
| @@ -9,121 +9,112 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| <script setup lang="ts"> | ||||
| import { onMounted, ref, watch } from 'vue'; | ||||
| import * as ace from 'ace-builds'; | ||||
| import { storeToRefs } from 'pinia'; | ||||
| import 'ace-builds/webpack-resolver'; | ||||
| import { storeToRefs } from 'pinia'; | ||||
| import { useSettingsStore } from '@/stores/settings'; | ||||
| import { uidGen } from 'common/libs/uidGen'; | ||||
|  | ||||
| export default { | ||||
|    name: 'BaseTextEditor', | ||||
|    props: { | ||||
|       modelValue: String, | ||||
|       mode: { type: String, default: 'text' }, | ||||
|       editorClass: { type: String, default: '' }, | ||||
|       autoFocus: { type: Boolean, default: false }, | ||||
|       readOnly: { type: Boolean, default: false }, | ||||
|       showLineNumbers: { type: Boolean, default: true }, | ||||
|       height: { type: Number, default: 200 } | ||||
|    }, | ||||
|    emits: ['update:modelValue'], | ||||
|    setup () { | ||||
|       const settingsStore = useSettingsStore(); | ||||
| const props = defineProps({ | ||||
|    modelValue: String, | ||||
|    mode: { type: String, default: 'text' }, | ||||
|    editorClass: { type: String, default: '' }, | ||||
|    autoFocus: { type: Boolean, default: false }, | ||||
|    readOnly: { type: Boolean, default: false }, | ||||
|    showLineNumbers: { type: Boolean, default: true }, | ||||
|    height: { type: Number, default: 200 } | ||||
| }); | ||||
| const emit = defineEmits(['update:modelValue']); | ||||
| const settingsStore = useSettingsStore(); | ||||
| const mode = ref(props.mode); | ||||
|  | ||||
|       const { | ||||
|          editorTheme, | ||||
|          editorFontSize, | ||||
|          autoComplete, | ||||
|          lineWrap | ||||
|       } = storeToRefs(settingsStore); | ||||
| const { | ||||
|    editorTheme, | ||||
|    editorFontSize, | ||||
|    autoComplete, | ||||
|    lineWrap | ||||
| } = storeToRefs(settingsStore); | ||||
|  | ||||
|       return { | ||||
|          editorTheme, | ||||
|          editorFontSize, | ||||
|          autoComplete, | ||||
|          lineWrap | ||||
|       }; | ||||
|    }, | ||||
|    data () { | ||||
|       return { | ||||
|          editor: null, | ||||
|          id: uidGen() | ||||
|       }; | ||||
|    }, | ||||
|    watch: { | ||||
|       mode () { | ||||
|          if (this.editor) | ||||
|             this.editor.session.setMode(`ace/mode/${this.mode}`); | ||||
|       }, | ||||
|       editorTheme () { | ||||
|          if (this.editor) | ||||
|             this.editor.setTheme(`ace/theme/${this.editorTheme}`); | ||||
|       }, | ||||
|       editorFontSize () { | ||||
|          const sizes = { | ||||
|             small: '12px', | ||||
|             medium: '14px', | ||||
|             large: '16px' | ||||
|          }; | ||||
| let editor: ace.Ace.Editor; | ||||
| const id = uidGen(); | ||||
|  | ||||
|          if (this.editor) { | ||||
|             this.editor.setOptions({ | ||||
|                fontSize: sizes[this.editorFontSize] | ||||
|             }); | ||||
|          } | ||||
|       }, | ||||
|       autoComplete () { | ||||
|          if (this.editor) { | ||||
|             this.editor.setOptions({ | ||||
|                enableLiveAutocompletion: this.autoComplete | ||||
|             }); | ||||
|          } | ||||
|       }, | ||||
|       lineWrap () { | ||||
|          if (this.editor) { | ||||
|             this.editor.setOptions({ | ||||
|                wrap: this.lineWrap | ||||
|             }); | ||||
|          } | ||||
|       } | ||||
|    }, | ||||
|    mounted () { | ||||
|       this.editor = ace.edit(`editor-${this.id}`, { | ||||
|          mode: `ace/mode/${this.mode}`, | ||||
|          theme: `ace/theme/${this.editorTheme}`, | ||||
|          value: this.modelValue || '', | ||||
|          fontSize: '14px', | ||||
|          printMargin: false, | ||||
|          readOnly: this.readOnly, | ||||
|          showLineNumbers: this.showLineNumbers, | ||||
|          showGutter: this.showLineNumbers | ||||
| watch(mode, () => { | ||||
|    if (editor) | ||||
|       editor.session.setMode(`ace/mode/${props.mode}`); | ||||
| }); | ||||
|  | ||||
| watch(editorTheme, () => { | ||||
|    if (editor) | ||||
|       editor.setTheme(`ace/theme/${editorTheme.value}`); | ||||
| }); | ||||
|  | ||||
| watch(editorFontSize, () => { | ||||
|    const sizes = { | ||||
|       small: 12, | ||||
|       medium: 14, | ||||
|       large: 16 | ||||
|    }; | ||||
|  | ||||
|    if (editor) { | ||||
|       editor.setOptions({ | ||||
|          fontSize: sizes[editorFontSize.value as undefined as 'small' | 'medium' | 'large'] | ||||
|       }); | ||||
|    } | ||||
| }); | ||||
|  | ||||
|       this.editor.setOptions({ | ||||
|          enableBasicAutocompletion: false, | ||||
|          wrap: this.lineWrap, | ||||
|          enableSnippets: false, | ||||
|          enableLiveAutocompletion: false | ||||
| watch(autoComplete, () => { | ||||
|    if (editor) { | ||||
|       editor.setOptions({ | ||||
|          enableLiveAutocompletion: autoComplete.value | ||||
|       }); | ||||
|    } | ||||
| }); | ||||
|  | ||||
|       this.editor.session.on('change', () => { | ||||
|          const content = this.editor.getValue(); | ||||
|          this.$emit('update:modelValue', content); | ||||
| watch(lineWrap, () => { | ||||
|    if (editor) { | ||||
|       editor.setOptions({ | ||||
|          wrap: lineWrap.value | ||||
|       }); | ||||
|    } | ||||
| }); | ||||
|  | ||||
|       if (this.autoFocus) { | ||||
|          setTimeout(() => { | ||||
|             this.editor.focus(); | ||||
|             this.editor.resize(); | ||||
|          }, 20); | ||||
|       } | ||||
| onMounted(() => { | ||||
|    editor = ace.edit(`editor-${id}`, { | ||||
|       mode: `ace/mode/${mode.value}`, | ||||
|       theme: `ace/theme/${editorTheme.value}`, | ||||
|       value: props.modelValue || '', | ||||
|       fontSize: 14, | ||||
|       printMargin: false, | ||||
|       readOnly: props.readOnly, | ||||
|       showLineNumbers: props.showLineNumbers, | ||||
|       showGutter: props.showLineNumbers | ||||
|    }); | ||||
|  | ||||
|    editor.setOptions({ | ||||
|       enableBasicAutocompletion: false, | ||||
|       wrap: lineWrap, | ||||
|       enableSnippets: false, | ||||
|       enableLiveAutocompletion: false | ||||
|    }); | ||||
|  | ||||
|    editor.session.on('changeFold', () => { | ||||
|       const content = editor.getValue(); | ||||
|       emit('update:modelValue', content); | ||||
|    }); | ||||
|  | ||||
|    if (props.autoFocus) { | ||||
|       setTimeout(() => { | ||||
|          this.editor.resize(); | ||||
|          editor.focus(); | ||||
|          editor.resize(); | ||||
|       }, 20); | ||||
|    } | ||||
| }; | ||||
|  | ||||
|    setTimeout(() => { | ||||
|       editor.resize(); | ||||
|    }, 20); | ||||
| }); | ||||
| </script> | ||||
|  | ||||
| <style lang="scss" scoped> | ||||
|   | ||||
| @@ -9,67 +9,64 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|    name: 'BaseToast', | ||||
|    props: { | ||||
|       message: { | ||||
|          type: String, | ||||
|          default: '' | ||||
|       }, | ||||
|       status: { | ||||
|          type: String, | ||||
|          default: '' | ||||
|       } | ||||
|    }, | ||||
|    emits: ['close'], | ||||
|    data () { | ||||
|       return { | ||||
|          isVisible: false | ||||
|       }; | ||||
|    }, | ||||
|    computed: { | ||||
|       toastStatus () { | ||||
|          let className = ''; | ||||
|          let iconName = ''; | ||||
|          switch (this.status) { | ||||
|             case 'success': | ||||
|                className = 'toast-success'; | ||||
|                iconName = 'mdi-check'; | ||||
|                break; | ||||
|             case 'error': | ||||
|                className = 'toast-error'; | ||||
|                iconName = 'mdi-alert-rhombus'; | ||||
|                break; | ||||
|             case 'warning': | ||||
|                className = 'toast-warning'; | ||||
|                iconName = 'mdi-alert'; | ||||
|                break; | ||||
|             case 'primary': | ||||
|                className = 'toast-primary'; | ||||
|                iconName = 'mdi-information-outline'; | ||||
|                break; | ||||
|          } | ||||
| <script setup lang="ts"> | ||||
| import { computed } from '@vue/reactivity'; | ||||
| import { ref, watch } from 'vue'; | ||||
|  | ||||
|          return { className, iconName }; | ||||
|       } | ||||
| const props = defineProps({ | ||||
|    message: { | ||||
|       type: String, | ||||
|       default: '' | ||||
|    }, | ||||
|    watch: { | ||||
|       message: function () { | ||||
|          if (this.message) | ||||
|             this.isVisible = true; | ||||
|          else | ||||
|             this.isVisible = false; | ||||
|       } | ||||
|    }, | ||||
|    methods: { | ||||
|       hideToast () { | ||||
|          this.isVisible = false; | ||||
|          this.$emit('close'); | ||||
|       } | ||||
|    status: { | ||||
|       type: String, | ||||
|       default: '' | ||||
|    } | ||||
| }); | ||||
|  | ||||
| const isVisible = ref(false); | ||||
| const message = ref(props.message); | ||||
|  | ||||
| const emit = defineEmits(['close']); | ||||
|  | ||||
| const toastStatus = computed(() => { | ||||
|    let className = ''; | ||||
|    let iconName = ''; | ||||
|    switch (props.status) { | ||||
|       case 'success': | ||||
|          className = 'toast-success'; | ||||
|          iconName = 'mdi-check'; | ||||
|          break; | ||||
|       case 'error': | ||||
|          className = 'toast-error'; | ||||
|          iconName = 'mdi-alert-rhombus'; | ||||
|          break; | ||||
|       case 'warning': | ||||
|          className = 'toast-warning'; | ||||
|          iconName = 'mdi-alert'; | ||||
|          break; | ||||
|       case 'primary': | ||||
|          className = 'toast-primary'; | ||||
|          iconName = 'mdi-information-outline'; | ||||
|          break; | ||||
|    } | ||||
|  | ||||
|    return { className, iconName }; | ||||
| }); | ||||
|  | ||||
| watch(message, () => { | ||||
|    if (message.value) | ||||
|       isVisible.value = true; | ||||
|    else | ||||
|       isVisible.value = false; | ||||
| }); | ||||
|  | ||||
| const hideToast = () => { | ||||
|    isVisible.value = false; | ||||
|    emit('close'); | ||||
| }; | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
|   .toast { | ||||
|     display: flex; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|          {{ lastPart(modelValue) }} | ||||
|       </span> | ||||
|       <i | ||||
|          v-if="modelValue.length" | ||||
|          v-if="modelValue" | ||||
|          class="file-uploader-reset mdi mdi-close" | ||||
|          @click.prevent="clear" | ||||
|       /> | ||||
| @@ -22,41 +22,35 @@ | ||||
|    </label> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|    name: 'BaseUploadInput', | ||||
|    props: { | ||||
|       message: { | ||||
|          default: 'Browse', | ||||
|          type: String | ||||
|       }, | ||||
|       modelValue: { | ||||
|          default: '', | ||||
|          type: String | ||||
|       } | ||||
|    }, | ||||
|    emits: ['change', 'clear'], | ||||
|    data () { | ||||
|       return { | ||||
|          id: null | ||||
|       }; | ||||
|    }, | ||||
|    mounted () { | ||||
|       this.id = this._uid; | ||||
|    }, | ||||
|    methods: { | ||||
|       clear () { | ||||
|          this.$emit('clear'); | ||||
|       }, | ||||
|       lastPart (string) { | ||||
|          if (!string) return ''; | ||||
| <script setup lang="ts"> | ||||
| import { uidGen } from 'common/libs/uidGen'; | ||||
|  | ||||
|          string = string.split(/[/\\]+/).pop(); | ||||
|          if (string.length >= 19) | ||||
|             string = `...${string.slice(-19)}`; | ||||
|          return string; | ||||
|       } | ||||
| defineProps({ | ||||
|    message: { | ||||
|       default: 'Browse', | ||||
|       type: String | ||||
|    }, | ||||
|    modelValue: { | ||||
|       default: '', | ||||
|       type: String | ||||
|    } | ||||
| }); | ||||
|  | ||||
| const emit = defineEmits(['change', 'clear']); | ||||
|  | ||||
| const id = uidGen(); | ||||
|  | ||||
| const clear = () => { | ||||
|    emit('clear'); | ||||
| }; | ||||
|  | ||||
| const lastPart = (string: string) => { | ||||
|    if (!string) return ''; | ||||
|  | ||||
|    string = string.split(/[/\\]+/).pop(); | ||||
|    if (string.length >= 19) | ||||
|       string = `...${string.slice(-19)}`; | ||||
|    return string; | ||||
| }; | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| <template> | ||||
|    <div class="vscroll-holder"> | ||||
|    <div ref="root" class="vscroll-holder"> | ||||
|       <div | ||||
|          class="vscroll-spacer" | ||||
|          :style="{ | ||||
| @@ -20,71 +20,77 @@ | ||||
|    </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| export default { | ||||
|    name: 'BaseVirtualScroll', | ||||
|    props: { | ||||
|       items: Array, | ||||
|       itemHeight: Number, | ||||
|       visibleHeight: Number, | ||||
|       scrollElement: { | ||||
|          type: HTMLDivElement, | ||||
|          default: null | ||||
|       } | ||||
|    }, | ||||
|    data () { | ||||
|       return { | ||||
|          topHeight: 0, | ||||
|          bottomHeight: 0, | ||||
|          visibleItems: [], | ||||
|          renderTimeout: null, | ||||
|          localScrollElement: null | ||||
|       }; | ||||
|    }, | ||||
|    watch: { | ||||
|       scrollElement () { | ||||
|          this.setScrollElement(); | ||||
|       } | ||||
|    }, | ||||
|    mounted () { | ||||
|       this.setScrollElement(); | ||||
|    }, | ||||
|    beforeUnmount () { | ||||
|       this.localScrollElement.removeEventListener('scroll', this.checkScrollPosition); | ||||
|    }, | ||||
|    methods: { | ||||
|       checkScrollPosition (e) { | ||||
|          clearTimeout(this.renderTimeout); | ||||
| <script setup lang="ts"> | ||||
| import { onBeforeUnmount, onMounted, Ref, ref, watch } from 'vue'; | ||||
|  | ||||
|          this.renderTimeout = setTimeout(() => { | ||||
|             this.updateWindow(e); | ||||
|          }, 200); | ||||
|       }, | ||||
|       updateWindow () { | ||||
|          const visibleItemsCount = Math.ceil(this.visibleHeight / this.itemHeight); | ||||
|          const totalScrollHeight = this.items.length * this.itemHeight; | ||||
|          const offset = 50; | ||||
|  | ||||
|          const scrollTop = this.localScrollElement.scrollTop; | ||||
|  | ||||
|          const firstVisibleIndex = Math.floor(scrollTop / this.itemHeight); | ||||
|          const lastVisibleIndex = firstVisibleIndex + visibleItemsCount; | ||||
|          const firstCutIndex = Math.max(firstVisibleIndex - offset, 0); | ||||
|          const lastCutIndex = lastVisibleIndex + offset; | ||||
|  | ||||
|          this.visibleItems = this.items.slice(firstCutIndex, lastCutIndex); | ||||
|  | ||||
|          this.topHeight = firstCutIndex * this.itemHeight; | ||||
|          this.bottomHeight = totalScrollHeight - this.visibleItems.length * this.itemHeight - this.topHeight; | ||||
|       }, | ||||
|       setScrollElement () { | ||||
|          if (this.localScrollElement) | ||||
|             this.localScrollElement.removeEventListener('scroll', this.checkScrollPosition); | ||||
|  | ||||
|          this.localScrollElement = this.scrollElement ? this.scrollElement : this.$el; | ||||
|          this.updateWindow(); | ||||
|          this.localScrollElement.addEventListener('scroll', this.checkScrollPosition); | ||||
|       } | ||||
| const props = defineProps({ | ||||
|    items: Array, | ||||
|    itemHeight: Number, | ||||
|    visibleHeight: Number, | ||||
|    scrollElement: { | ||||
|       type: HTMLDivElement, | ||||
|       default: null | ||||
|    } | ||||
| }); | ||||
|  | ||||
| const root = ref(null); | ||||
| const topHeight: Ref<number> = ref(0); | ||||
| const bottomHeight: Ref<number> = ref(0); | ||||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||||
| const visibleItems: Ref<any[]> = ref([]); | ||||
| const renderTimeout: Ref<NodeJS.Timeout> = ref(null); | ||||
| const localScrollElement: Ref<HTMLDivElement> = ref(null); | ||||
| const scrollElement = ref(props.scrollElement); | ||||
|  | ||||
| const checkScrollPosition = () => { | ||||
|    clearTimeout(renderTimeout.value); | ||||
|  | ||||
|    renderTimeout.value = setTimeout(() => { | ||||
|       updateWindow(); | ||||
|    }, 200); | ||||
| }; | ||||
|  | ||||
| const updateWindow = () => { | ||||
|    const visibleItemsCount = Math.ceil(props.visibleHeight / props.itemHeight); | ||||
|    const totalScrollHeight = props.items.length * props.itemHeight; | ||||
|    const offset = 50; | ||||
|  | ||||
|    const scrollTop = localScrollElement.value.scrollTop; | ||||
|  | ||||
|    const firstVisibleIndex = Math.floor(scrollTop / props.itemHeight); | ||||
|    const lastVisibleIndex = firstVisibleIndex + visibleItemsCount; | ||||
|    const firstCutIndex = Math.max(firstVisibleIndex - offset, 0); | ||||
|    const lastCutIndex = lastVisibleIndex + offset; | ||||
|  | ||||
|    visibleItems.value = props.items.slice(firstCutIndex, lastCutIndex); | ||||
|  | ||||
|    topHeight.value = firstCutIndex * props.itemHeight; | ||||
|    bottomHeight.value = totalScrollHeight - visibleItems.value.length * props.itemHeight - topHeight.value; | ||||
| }; | ||||
|  | ||||
| const setScrollElement = () => { | ||||
|    if (localScrollElement.value) | ||||
|       localScrollElement.value.removeEventListener('scroll', checkScrollPosition); | ||||
|  | ||||
|    localScrollElement.value = scrollElement.value ? scrollElement.value : root.value; | ||||
|    updateWindow(); | ||||
|    localScrollElement.value.addEventListener('scroll', checkScrollPosition); | ||||
| }; | ||||
|  | ||||
| watch(scrollElement, () => { | ||||
|    setScrollElement(); | ||||
| }); | ||||
|  | ||||
| onMounted(() => { | ||||
|    setScrollElement(); | ||||
| }); | ||||
|  | ||||
| onBeforeUnmount(() => { | ||||
|    localScrollElement.value.removeEventListener('scroll', checkScrollPosition); | ||||
| }); | ||||
|  | ||||
| defineExpose({ | ||||
|    updateWindow | ||||
| }); | ||||
|  | ||||
| </script> | ||||
|   | ||||
| @@ -52,7 +52,7 @@ | ||||
|       > | ||||
|       <BaseUploadInput | ||||
|          v-else-if="inputProps().type === 'file'" | ||||
|          :value="selectedValue" | ||||
|          :model-value="selectedValue" | ||||
|          :message="$t('word.browse')" | ||||
|          @clear="clearValue" | ||||
|          @change="filesChange($event)" | ||||
|   | ||||
| @@ -134,7 +134,7 @@ | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import arrayToFile from '../libs/arrayToFile'; | ||||
| import { arrayToFile } from '../libs/arrayToFile'; | ||||
| import { useNotificationsStore } from '@/stores/notifications'; | ||||
| import Schema from '@/ipc-api/Schema'; | ||||
| import { useConnectionsStore } from '@/stores/connections'; | ||||
|   | ||||
| @@ -328,7 +328,7 @@ import { storeToRefs } from 'pinia'; | ||||
| import { useApplicationStore } from '@/stores/application'; | ||||
| import { useSettingsStore } from '@/stores/settings'; | ||||
| import { useWorkspacesStore } from '@/stores/workspaces'; | ||||
| import localesNames from '@/i18n/supported-locales'; | ||||
| import { localesNames } from '@/i18n/supported-locales'; | ||||
| import ModalSettingsUpdate from '@/components/ModalSettingsUpdate'; | ||||
| import ModalSettingsChangelog from '@/components/ModalSettingsChangelog'; | ||||
| import BaseTextEditor from '@/components/BaseTextEditor'; | ||||
|   | ||||
| @@ -96,7 +96,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="connection.databasePath" | ||||
|                               :model-value="connection.databasePath" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('databasePath')" | ||||
|                               @change="pathSelection($event, 'databasePath')" | ||||
| @@ -211,7 +211,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="connection.key" | ||||
|                               :model-value="connection.key" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('key')" | ||||
|                               @change="pathSelection($event, 'key')" | ||||
| @@ -224,7 +224,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="connection.cert" | ||||
|                               :model-value="connection.cert" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('cert')" | ||||
|                               @change="pathSelection($event, 'cert')" | ||||
| @@ -237,7 +237,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="connection.ca" | ||||
|                               :model-value="connection.ca" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('ca')" | ||||
|                               @change="pathSelection($event, 'ca')" | ||||
| @@ -342,7 +342,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="connection.sshKey" | ||||
|                               :model-value="connection.sshKey" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('sshKey')" | ||||
|                               @change="pathSelection($event, 'sshKey')" | ||||
|   | ||||
| @@ -92,7 +92,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="localConnection.databasePath" | ||||
|                               :model-value="localConnection.databasePath" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('databasePath')" | ||||
|                               @change="pathSelection($event, 'databasePath')" | ||||
| @@ -207,7 +207,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="localConnection.key" | ||||
|                               :model-value="localConnection.key" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('key')" | ||||
|                               @change="pathSelection($event, 'key')" | ||||
| @@ -220,7 +220,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="localConnection.cert" | ||||
|                               :model-value="localConnection.cert" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('cert')" | ||||
|                               @change="pathSelection($event, 'cert')" | ||||
| @@ -233,7 +233,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="localConnection.ca" | ||||
|                               :model-value="localConnection.ca" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('ca')" | ||||
|                               @change="pathSelection($event, 'ca')" | ||||
| @@ -330,7 +330,7 @@ | ||||
|                         </div> | ||||
|                         <div class="column col-8 col-sm-12"> | ||||
|                            <BaseUploadInput | ||||
|                               :value="localConnection.sshKey" | ||||
|                               :model-value="localConnection.sshKey" | ||||
|                               :message="$t('word.browse')" | ||||
|                               @clear="pathClear('sshKey')" | ||||
|                               @change="pathSelection($event, 'sshKey')" | ||||
|   | ||||
| @@ -90,7 +90,7 @@ | ||||
|          </label> | ||||
|       </div> | ||||
|       <div class="td p-0 type-int" tabindex="0"> | ||||
|          <template v-if="fieldType.length"> | ||||
|          <template v-if="fieldType?.length"> | ||||
|             <span | ||||
|                v-if="!isInlineEditor.length" | ||||
|                class="cell-content" | ||||
| @@ -355,7 +355,7 @@ export default { | ||||
|    }, | ||||
|    props: { | ||||
|       row: Object, | ||||
|       dataTypes: Array, | ||||
|       dataTypes: { type: Array, default: () => [] }, | ||||
|       indexes: Array, | ||||
|       foreigns: Array, | ||||
|       customizations: Object | ||||
|   | ||||
| @@ -112,7 +112,7 @@ import { uidGen } from 'common/libs/uidGen'; | ||||
| import { useNotificationsStore } from '@/stores/notifications'; | ||||
| import { useSettingsStore } from '@/stores/settings'; | ||||
| import { useWorkspacesStore } from '@/stores/workspaces'; | ||||
| import arrayToFile from '../libs/arrayToFile'; | ||||
| import { arrayToFile } from '../libs/arrayToFile'; | ||||
| import { TEXT, LONG_TEXT, BLOB } from 'common/fieldTypes'; | ||||
| import BaseVirtualScroll from '@/components/BaseVirtualScroll'; | ||||
| import WorkspaceTabQueryTableRow from '@/components/WorkspaceTabQueryTableRow'; | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| export default { | ||||
| export const localesNames = { | ||||
|    'en-US': 'English', | ||||
|    'it-IT': 'Italiano', | ||||
|    'ar-SA': 'العربية', | ||||
| @@ -29,7 +29,7 @@ createApp(App) | ||||
|    .mount('#app'); | ||||
| 
 | ||||
| const { locale } = useSettingsStore(); | ||||
| i18n.global.locale = locale; | ||||
| i18n.global.locale = locale as string;// TODO: temp
 | ||||
| 
 | ||||
| // IPC exceptions
 | ||||
| ipcRenderer.on('unhandled-exception', (event, error) => { | ||||
| @@ -59,7 +59,7 @@ ipcRenderer.on('no-auto-update', () => { | ||||
| 
 | ||||
| ipcRenderer.on('download-progress', (event, data) => { | ||||
|    useApplicationStore().updateStatus = 'downloading'; | ||||
|    useApplicationStore().downloadprogress = data.percent; | ||||
|    useApplicationStore().downloadProgress = data.percent; | ||||
| }); | ||||
| 
 | ||||
| ipcRenderer.on('update-downloaded', () => { | ||||
| @@ -4,6 +4,9 @@ import Connection from '@/ipc-api/Connection'; | ||||
| import Schema from '@/ipc-api/Schema'; | ||||
| import Users from '@/ipc-api/Users'; | ||||
| import { uidGen } from 'common/libs/uidGen'; | ||||
|  | ||||
| import customizations from 'common/customizations'; | ||||
|  | ||||
| import { useConnectionsStore } from '@/stores/connections'; | ||||
| import { useNotificationsStore } from '@/stores/notifications'; | ||||
| import { useSettingsStore } from '@/stores/settings'; | ||||
| @@ -22,14 +25,14 @@ export const useWorkspacesStore = defineStore('workspaces', { | ||||
|          if (state.selectedWorkspace) return state.selectedWorkspace; | ||||
|          return state.workspaces[0].uid; | ||||
|       }, | ||||
|       getWorkspace: state => uid => { | ||||
|       getWorkspace: state => (uid) => { | ||||
|          return state.workspaces.find(workspace => workspace.uid === uid); | ||||
|       }, | ||||
|       getDatabaseVariable: state => (uid, name) => { | ||||
|          return state.workspaces.find(workspace => workspace.uid === uid).variables.find(variable => variable.name === name); | ||||
|       }, | ||||
|       getWorkspaceTab (state) { | ||||
|          return tUid => { | ||||
|          return (tUid) => { | ||||
|             if (!this.getSelected) return; | ||||
|             const workspace = state.workspaces.find(workspace => workspace.uid === this.getSelected); | ||||
|             if ('tabs' in workspace) | ||||
| @@ -89,24 +92,24 @@ export const useWorkspacesStore = defineStore('workspaces', { | ||||
|             else { | ||||
|                let dataTypes = []; | ||||
|                let indexTypes = []; | ||||
|                let customizations = {}; | ||||
|                let clientCustomizations; | ||||
|  | ||||
|                switch (connection.client) { | ||||
|                   case 'mysql': | ||||
|                   case 'maria': | ||||
|                      dataTypes = require('common/data-types/mysql'); | ||||
|                      indexTypes = require('common/index-types/mysql'); | ||||
|                      customizations = require('common/customizations/mysql'); | ||||
|                      dataTypes = require('common/data-types/mysql').default; | ||||
|                      indexTypes = require('common/index-types/mysql').default; | ||||
|                      clientCustomizations = customizations.mysql; | ||||
|                      break; | ||||
|                   case 'pg': | ||||
|                      dataTypes = require('common/data-types/postgresql'); | ||||
|                      indexTypes = require('common/index-types/postgresql'); | ||||
|                      customizations = require('common/customizations/postgresql'); | ||||
|                      dataTypes = require('common/data-types/postgresql').default; | ||||
|                      indexTypes = require('common/index-types/postgresql').default; | ||||
|                      clientCustomizations = customizations.pg; | ||||
|                      break; | ||||
|                   case 'sqlite': | ||||
|                      dataTypes = require('common/data-types/sqlite'); | ||||
|                      indexTypes = require('common/index-types/sqlite'); | ||||
|                      customizations = require('common/customizations/sqlite'); | ||||
|                      dataTypes = require('common/data-types/sqlite').default; | ||||
|                      indexTypes = require('common/index-types/sqlite').default; | ||||
|                      clientCustomizations = customizations.sqlite; | ||||
|                      break; | ||||
|                } | ||||
|  | ||||
| @@ -144,7 +147,7 @@ export const useWorkspacesStore = defineStore('workspaces', { | ||||
|                      client: connection.client, | ||||
|                      dataTypes, | ||||
|                      indexTypes, | ||||
|                      customizations, | ||||
|                      customizations: clientCustomizations, | ||||
|                      structure: response, | ||||
|                      connectionStatus: 'connected', | ||||
|                      tabs: cachedTabs, | ||||
|   | ||||
							
								
								
									
										2
									
								
								src/renderer/untyped.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/renderer/untyped.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| declare module '@/App.vue'; | ||||
| declare module 'v-mask'; | ||||
		Reference in New Issue
	
	Block a user