Browse Source

fix issues from PR

pull/4749/head
flisowna 2 years ago
parent
commit
c2220c6a6b
  1. 10
      packages/nc-gui/components/cell/GeoData.vue
  2. 10
      packages/nc-gui/components/dlg/ViewCreate.vue
  3. 1
      packages/nc-gui/components/smartsheet/Gallery.vue
  4. 3
      packages/nc-gui/components/smartsheet/Kanban.vue
  5. 43
      packages/nc-gui/components/smartsheet/Map.vue
  6. 7
      packages/nc-gui/components/smartsheet/toolbar/MappedBy.vue
  7. 8
      packages/nc-gui/composables/useMapViewDataStore.ts
  8. 17
      packages/nc-gui/composables/useSmartsheetStore.ts
  9. 3
      packages/nc-gui/composables/useViewData.ts
  10. 1
      packages/nc-gui/context/index.ts
  11. 8
      packages/nc-gui/lang/en.json
  12. 3
      packages/nocodb/src/lib/migrations/v2/nc_025_map_view_column.ts
  13. 9
      packages/nocodb/src/lib/models/View.ts

10
packages/nc-gui/components/cell/GeoData.vue

@ -73,7 +73,7 @@ const onClickSetCurrentLocation = () => {
<a-button>{{ latLongStr }}</a-button>
<template #overlay>
<a-form :model="formState" class="flex flex-col" @finish="handleFinish">
<a-form-item class="inputLat" label="Lat">
<a-form-item class="inputLat" :label="$t('labels.lat')">
<a-input
v-model:value="formState.latitude"
type="number"
@ -91,7 +91,7 @@ const onClickSetCurrentLocation = () => {
/>
</a-form-item>
<a-form-item class="inputLng" label="Lng">
<a-form-item class="inputLng" :label="$t('labels.lng')">
<a-input
v-model:value="formState.longitude"
type="number"
@ -111,12 +111,12 @@ const onClickSetCurrentLocation = () => {
<a-form-item>
<div style="display: flex; align-items: center; margin-right: 0.5rem">
<MdiReload v-if="isLoading" :class="{ 'animate-infinite animate-spin text-gray-500': isLoading }" />
<a-button class="ml-2" @click="onClickSetCurrentLocation">Your Location</a-button>
<a-button class="ml-2" @click="onClickSetCurrentLocation">{{ $t('labels.yourLocation') }}</a-button>
</div>
</a-form-item>
<a-form-item class="buttons">
<a-button type="text" @click="clear">Cancel</a-button>
<a-button type="primary" html-type="submit">Submit</a-button>
<a-button type="text" @click="clear">{{ $t('general.cancel') }}</a-button>
<a-button type="primary" html-type="submit">{{ $t('general.submit') }}</a-button>
</a-form-item>
</a-form>
</template>

10
packages/nc-gui/components/dlg/ViewCreate.vue

@ -83,15 +83,9 @@ const viewNameRules = [
},
]
const groupingFieldColumnRules = [
// name is required
{ required: true, message: `${t('general.groupingField')} ${t('general.required')}` },
]
const groupingFieldColumnRules = [{ required: true, message: `${t('general.groupingField')} ${t('general.required')}` }]
const geoDataFieldColumnRules = [
// name is required
{ required: true, message: `${t('general.geoDataField')} ${t('general.required')}` },
]
const geoDataFieldColumnRules = [{ required: true, message: `${t('general.geoDataField')} ${t('general.required')}` }]
const typeAlias = computed(
() =>

1
packages/nc-gui/components/smartsheet/Gallery.vue

@ -105,7 +105,6 @@ const expandForm = (row: RowType, state?: Record<string, any>) => {
expandedFormRow.value = row
expandedFormRowState.value = state
expandedFormDlg.value = true
console.log(state)
}
}

3
packages/nc-gui/components/smartsheet/Kanban.vue

@ -12,7 +12,6 @@ import {
IsPublicInj,
MetaInj,
OpenNewRecordFormHookInj,
ReadonlyInj,
inject,
onBeforeMount,
onBeforeUnmount,
@ -85,8 +84,6 @@ provide(IsGridInj, ref(false))
provide(IsKanbanInj, ref(true))
provide(ReadonlyInj, !isUIAllowed('xcDatatableEditable'))
const hasEditPermission = $computed(() => isUIAllowed('xcDatatableEditable'))
const fields = inject(FieldsInj, ref([]))

43
packages/nc-gui/components/smartsheet/Map.vue

@ -3,35 +3,44 @@ import 'leaflet/dist/leaflet.css'
import L, { LatLng } from 'leaflet'
import 'leaflet.markercluster'
import { ViewTypes } from 'nocodb-sdk'
// import contextmenu from 'vue3-contextmenu'
// import 'vue3-contextmenu/dist/vue3-contextmenu.css'
import { IsGalleryInj, IsGridInj, IsMapInj, OpenNewRecordFormHookInj, onMounted, provide, ref } from '#imports'
import type { Row as RowType } from '~/lib'
import { latLongToJoinedString } from '~~/utils/geoDataUtils'
provide(IsGalleryInj, ref(false))
provide(IsGridInj, ref(false))
provide(IsMapInj, ref(true))
const route = useRoute()
const router = useRouter()
const reloadViewDataHook = inject(ReloadViewDataHookInj)
const reloadViewMetaHook = inject(ReloadViewMetaHookInj)
const { formattedData, loadMapData, loadMapMeta, mapMetaData, geoDataFieldColumn, addEmptyRow, syncCount, paginationData } =
useMapViewStoreOrThrow()
const markersClusterGroupRef = ref<L.MarkerClusterGroup>()
const mapContainerRef = ref<HTMLElement>()
const myMapRef = ref<L.Map>()
const meta = inject(MetaInj, ref())
const view = inject(ActiveViewInj, ref())
const openNewRecordFormHook = inject(OpenNewRecordFormHookInj, createEventHook())
const expandedFormDlg = ref(false)
const expandedFormRow = ref<RowType>()
const expandedFormRowState = ref<Record<string, any>>()
const expandedFormClickedLatLongForNewRow = ref<[number, number]>()
const fallBackCenterLocation = {
lat: 51,
@ -39,11 +48,11 @@ const fallBackCenterLocation = {
}
const getMapZoomLocalStorageKey = (viewId: string) => {
return `mapView.zoom.${viewId}`
return `mapView.${viewId}.zoom`
}
const getMapCenterLocalStorageKey = (viewId: string) => `mapView.center.${viewId}`
const getMapCenterLocalStorageKey = (viewId: string) => `mapView.${viewId}.center`
const expandForm = (row: RowType, state?: Record<string, any>, clickedLatLongForNewRow?: [number, number]) => {
const expandForm = (row: RowType, state?: Record<string, any>) => {
const rowId = extractPkFromRow(row.row, meta.value!.columns!)
if (rowId) {
router.push({
@ -53,13 +62,9 @@ const expandForm = (row: RowType, state?: Record<string, any>, clickedLatLongFor
},
})
} else {
expandedFormClickedLatLongForNewRow.value = clickedLatLongForNewRow
expandedFormRow.value = row
expandedFormRowState.value = state
expandedFormDlg.value = true
// const lat = state?.lat
// const lng = state?.lng
}
}
@ -85,7 +90,7 @@ const expandedFormOnRowIdDlg = computed({
const addMarker = (lat: number, long: number, row: RowType) => {
if (markersClusterGroupRef.value == null) {
throw new Error('Map is null')
throw new Error('Marker cluster is null')
}
const newMarker = L.marker([lat, long]).on('click', () => {
expandForm(row)
@ -98,7 +103,6 @@ const resetZoomAndCenterBasedOnLocalStorage = () => {
return
}
const initialZoomLevel = parseInt(localStorage.getItem(getMapZoomLocalStorageKey(mapMetaData.value.fk_view_id)) || '10')
const initialCenterLocalStorageStr = localStorage.getItem(getMapCenterLocalStorageKey(mapMetaData.value.fk_view_id))
const initialCenter = initialCenterLocalStorageStr ? JSON.parse(initialCenterLocalStorageStr) : fallBackCenterLocation
@ -142,13 +146,12 @@ onMounted(async () => {
})
myMap.on('contextmenu', async function (e) {
const lat = e.latlng.lat
const lng = e.latlng.lng
const { lat, lng } = e.latlng
const newRow = await addEmptyRow()
if (geoDataFieldColumn.value?.title) {
newRow.row[geoDataFieldColumn.value.title] = latLongToJoinedString(lat, lng)
}
expandForm(newRow, [lat, lng])
expandForm(newRow)
})
})
@ -205,13 +208,13 @@ const count = computed(() => paginationData.value.totalRows)
<div id="mapContainer" ref="mapContainerRef">
<a-tooltip placement="bottom" class="tooltip">
<template #title>
<span v-if="count > 1000"> You're over the limit. </span>
<span v-else> You're getting close to the limit. </span>
<span> The limit of markers shown in a Map View is 1000 records. </span>
<span v-if="count > 1000"> {{ $t('msg.info.map.overLimit') }} </span>
<span v-else-if="count > 900"> {{ $t('msg.info.map.closeLimit') }} </span>
<span> {{ $t('msg.info.map.limitNumber') }} </span>
</template>
<div v-if="count > 900" class="nc-warning-info flex min-w-32px h-32px items-center gap-1 px-2 bg-white">
<div>{{ count }} records</div>
<div>{{ count }} {{ $t('objects.records') }}</div>
<mdi-map-marker-alert />
</div>
</a-tooltip>

7
packages/nc-gui/components/smartsheet/toolbar/MappedBy.vue

@ -72,12 +72,7 @@ const handleChange = () => {
</script>
<template>
<a-dropdown
v-if="!IsPublic"
v-model:visible="stackedByDropdown"
:trigger="['click']"
overlay-class-name="nc-dropdown-kanban-stacked-by-menu"
>
<a-dropdown v-if="!IsPublic" v-model:visible="stackedByDropdown" :trigger="['click']">
<div class="nc-kanban-btn">
<a-button
v-e="['c:kanban:change-grouping-field']"

8
packages/nc-gui/composables/useMapViewDataStore.ts

@ -7,11 +7,14 @@ import type { Row } from '~/lib'
export const geodataToggleState = reactive({ show: false })
const formatData = (list: Record<string, any>[]) =>
list.map((row) => ({
list.map(
(row) =>
({
row: { ...row },
oldRow: { ...row },
rowMeta: {},
}))
} as Row),
)
const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
(
@ -73,7 +76,6 @@ const [useProvideMapViewStore, useMapViewStore] = useInjectionState(
}
async function loadMapData() {
if ((!project?.value?.id || !meta.value?.id || !viewMeta.value?.id) && !isPublic?.value) return
const res = !isPublic.value

17
packages/nc-gui/composables/useSmartsheetStore.ts

@ -12,23 +12,9 @@ const [useProvideSmartsheetStore, useSmartsheetStore] = useInjectionState(
initialSorts?: Ref<SortType[]>,
initialFilters?: Ref<FilterType[]>,
) => {
// const paginatedData = inject(PaginationDataInj)!
// const { paginationData } = useViewData(meta, view)
// debugger
const { $api } = useNuxtApp()
const { sqlUis, project } = useProject()
const totalNumberOfTableRows = ref(async () => {
const { count } = await $api.dbViewRow.count(
NOCO,
project?.value?.title as string,
meta?.value?.id as string,
meta?.value?.id as string,
)
return count
})
const sqlUi = ref(meta.value?.base_id ? sqlUis.value[meta.value?.base_id] : Object.values(sqlUis.value)[0])
const cellRefs = ref<HTMLTableDataCellElement[]>([])
@ -37,8 +23,6 @@ const [useProvideSmartsheetStore, useSmartsheetStore] = useInjectionState(
const eventBus = useEventBus<SmartsheetStoreEvents>(Symbol('SmartsheetStore'))
// getters
// const count = computed(() => paginatedData.value?.totalRows ?? Infinity)
const isLocked = computed(() => view.value?.lock_type === 'locked')
const isPkAvail = computed(() => (meta.value as TableType)?.columns?.some((c) => c.pk))
const isGrid = computed(() => view.value?.type === ViewTypes.GRID)
@ -68,7 +52,6 @@ const [useProvideSmartsheetStore, useSmartsheetStore] = useInjectionState(
const nestedFilters = ref<FilterType[]>(unref(initialFilters) ?? [])
return {
totalNumberOfTableRows,
view,
meta,
isLocked,

3
packages/nc-gui/composables/useViewData.ts

@ -209,7 +209,6 @@ export function useViewData(
async function insertRow(
currentRow: Row,
_rowIndex = formattedData.value?.length,
ltarState: Record<string, any> = {},
{ metaValue = meta.value, viewMetaValue = viewMeta.value }: { metaValue?: TableType; viewMetaValue?: ViewType } = {},
) {
@ -323,7 +322,7 @@ export function useViewData(
await until(() => !(row.rowMeta?.new && row.rowMeta?.saving)).toMatch((v) => v)
if (row.rowMeta.new) {
return await insertRow(row, formattedData.value.indexOf(row), ltarState, args)
return await insertRow(row, ltarState, args)
} else {
// if the field name is missing skip update
if (property) {

1
packages/nc-gui/context/index.ts

@ -17,7 +17,6 @@ export const IsFormInj: InjectionKey<Ref<boolean>> = Symbol('is-form-injection')
export const IsGridInj: InjectionKey<Ref<boolean>> = Symbol('is-grid-injection')
export const IsGalleryInj: InjectionKey<Ref<boolean>> = Symbol('is-gallery-injection')
export const IsMapInj: InjectionKey<Ref<boolean>> = Symbol('is-map-injection')
export const IsGeodataActiveInj: InjectionKey<Ref<boolean>> = Symbol('is-geodata-active-injection')
export const IsKanbanInj: InjectionKey<Ref<boolean>> = Symbol('is-kanban-injection')
export const IsLockedInj: InjectionKey<Ref<boolean>> = Symbol('is-locked-injection')
export const CellValueInj: InjectionKey<Ref<any>> = Symbol('cell-value-injection')

8
packages/nc-gui/lang/en.json

@ -250,6 +250,9 @@
"barcodeFormat": "Barcode format",
"qrCodeValueTooLong": "Too many characters for a QR code",
"barcodeValueTooLong": "Too many characters for a barcode",
"yourLocation": "Your Location",
"lng": "Lng",
"lat": "Lat",
"aggregateFunction": "Aggregate function",
"dbCreateIfNotExists": "Database : create if not exists",
"clientKey": "Client Key",
@ -515,6 +518,11 @@
"orgCreator": "Creator can create new projects and access any invited project.",
"orgViewer": "Viewer is not allowed to create new projects but they can access any invited project."
},
"map": {
"overLimit": "You're over the limit.",
"closeLimit": "You're getting close to the limit.",
"limitNumber": "The limit of markers shown in a Map View is 1000 records."
},
"footerInfo": "Rows per page",
"upload": "Select file to Upload",
"upload_sub": "or drag and drop file",

3
packages/nocodb/src/lib/migrations/v2/nc_025_map_view_column.ts

@ -5,9 +5,7 @@ const up = async (knex) => {
table.string('id', 20).primary().notNullable();
table.string('base_id', 20);
// table.foreign('base_id').references(`${MetaTable.BASES}.id`);
table.string('project_id', 128);
// table.foreign('project_id').references(`${MetaTable.PROJECT}.id`);
table.string('fk_view_id', 20);
table.foreign('fk_view_id').references(`${MetaTable.MAP_VIEW}.fk_view_id`);
@ -16,7 +14,6 @@ const up = async (knex) => {
table.string('uuid');
// todo: type
table.string('label');
table.string('help');

9
packages/nocodb/src/lib/models/View.ts

@ -433,7 +433,7 @@ export default class View implements ViewType {
show = false;
}
}
// TODO: Check whether/what we need to do here for properly integrate MapView
else if (view.type === ViewTypes.KANBAN && !copyFromView) {
const kanbanView = await KanbanView.get(view_id, ncMeta);
if (vCol.id === kanbanView?.fk_grp_col_id) {
@ -453,6 +453,13 @@ export default class View implements ViewType {
}
}
else if (view.type === ViewTypes.MAP && !copyFromView) {
const mapView = await MapView.get(view_id, ncMeta);
if (vCol.id === mapView?.fk_geo_data_col_id) {
show = true;
}
}
// if columns is list of virtual columns then get the parent column
const col = vCol.fk_column_id
? await Column.get({ colId: vCol.fk_column_id }, ncMeta)

Loading…
Cancel
Save