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