Skip to content

Commit

Permalink
feat(print): complete spec generation & plug
Browse files Browse the repository at this point in the history
  • Loading branch information
tonio committed Dec 20, 2024
1 parent 8934960 commit 112fa65
Show file tree
Hide file tree
Showing 7 changed files with 399 additions and 103 deletions.
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"dependencies": {
"@braintree/sanitize-url": "^7.1.0",
"@camptocamp/ogc-client": "^0.3.4",
"@geoblocks/mapfishprint": "0.2.18",
"d3-array": "^3.2.4",
"d3-axis": "^3.0.0",
"d3-scale": "^4.0.2",
Expand Down
173 changes: 82 additions & 91 deletions src/bundle/lib.ts
Original file line number Diff line number Diff line change
@@ -1,80 +1,71 @@
import {
h,
getCurrentInstance,
createApp,
watch,
// defineCustomElement, // TODO: Update vue package and use this defineCustomElement
} from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'
import { createPinia, storeToRefs } from 'pinia'

import { initProjections } from '@/services/projection.utils'
import { defineCustomElement } from '@/bundle/runtime-dom/apiCustomElement'
import { initProjections } from '@/services/projection.utils'
import { createPinia, storeToRefs } from 'pinia'
import { createApp, getCurrentInstance, h, watch } from 'vue'
import VueDOMPurifyHTML from 'vue-dompurify-html'

initProjections()

import './lib.css' // Tell Vite to build the css
import '../assets/main.css' // Tell Vite to build the css
import './lib.css' // Tell Vite to build the css

import AlertNotifications from '@/components/alert-notifications/alert-notifications.vue'
import AuthForm from '@/components/auth/auth-form.vue'
import DropdownList from '@/components/common/dropdown-list.vue'
import MapContainer from '@/components/map/map-container.vue'
import BackgroundSelector from '@/components/background-selector/background-selector.vue'
import RemoteLayers from '@/components/remote-layers/remote-layers.vue'
import LayerMetadata from '@/components/layer-metadata/layer-metadata.vue'
import HeaderBar from '@/components/header-bar/header-bar.vue'
import ProfileDraw from './components/profile_v3/profile-draw_v3.vue'
import ProfileMeasures from './components/profile_v3/profile-measures_v3.vue'
import ProfileRouting from './components/profile_v3/profile-routing_v3.vue'
import ProfileInfos from './components/profile_v3/profile-infos_v3.vue'
import DropdownList from '@/components/common/dropdown-list.vue'
import FooterBar from '@/components/footer/footer-bar.vue'
import ToolbarDraw from '@/components/footer/toolbar-draw.vue'
import HeaderBar from '@/components/header-bar/header-bar.vue'
import LocationInfoPanel from '@/components/info/location-info.vue'
import LayerMetadata from '@/components/layer-metadata/layer-metadata.vue'
import LayerPanel from '@/components/layer-panel/layer-panel.vue'
import LegendsPanel from '@/components/legends/legends-panel.vue'
import LocationInfoPanel from '@/components/info/location-info.vue'
import MapContainer from '@/components/map/map-container.vue'
import RemoteLayers from '@/components/remote-layers/remote-layers.vue'
import SliderComparator from '@/components/slider/slider-comparator.vue'
import StylePanel from '@/components/style-selector/style-panel.vue'
import { themeSelectorService } from '@/components/theme-selector/theme-selector.service'
import useBackgroundLayer from '@/composables/background-layer/background-layer.composable'
import useLayers from '@/composables/layers/layers.composable'
import useMap from '@/composables/map/map.composable'
import useMvtStyles from '@/composables/mvt-styles/mvt-styles.composable'
import useOpenLayers from '@/composables/map/ol.composable'
import useThemes from '@/composables/themes/themes.composable'
import useOffline from '@/composables/offline/offline.composable'
import useMvtStyles from '@/composables/mvt-styles/mvt-styles.composable'
import useOfflineLayers from '@/composables/offline/offline-layers.composable'
import { useAppStore } from '@/stores/app.store'
import { useMapStore } from '@/stores/map.store'
import { useProfileDrawv3Store } from './stores/profile-draw_v3.store'
import { useProfileMeasuresv3Store } from './stores/profile-measures_v3.store'
import { useProfileRoutingv3Store } from './stores/profile-routing_v3.store'
import { useProfileInfosv3Store } from './stores/profile-infos_v3.store'
import { useDrawStore } from '@/stores/draw.store'
import { useLocationInfoStore } from '@/stores/location-info.store'
import { useStyleStore } from '@/stores/style.store'
import { useThemeStore } from '@/stores/config.store'
import { useUserManagerStore } from '@/stores/user-manager.store'
import useOffline from '@/composables/offline/offline.composable'
import useThemes from '@/composables/themes/themes.composable'
import formatMeasureDirective from '@/directives/format-measure.directive'
import MapLibreLayer from '@/lib/ol-mapbox-layer'
import { Mask as MaskLayer } from '@/lib/ol-mask-layer'
import { layerMetadataService } from '@/services/layer-metadata/layer-metadata.service'
import { statePersistorBgLayerService } from '@/services/state-persistor/state-persistor-layer-background.service'
import { statePersistorLayersService } from '@/services/state-persistor/state-persistor-layers.service'
import { statePersistorThemeService } from '@/services/state-persistor/state-persistor-theme.service'
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'
import { statePersistorAppService } from '@/services/state-persistor/state-persistor-app.service'
import { statePersistorStyleService } from '@/services/state-persistor/state-persistor-bgstyle.service'
import { statePersistorBgLayerService } from '@/services/state-persistor/state-persistor-layer-background.service'
import { statePersistorLayersService } from '@/services/state-persistor/state-persistor-layers.service'
import { statePersistorMyMapService } from '@/services/state-persistor/state-persistor-mymap.service'
import { proxyUrlHelper } from '@/services/proxyurl/proxyurl.helper'
import { styleUrlHelper } from '@/services/styleurl/styleurl.helper'
import { statePersistorThemeService } from '@/services/state-persistor/state-persistor-theme.service'
import { storageHelper } from '@/services/state-persistor/storage/storage.helper'
import { themeSelectorService } from '@/components/theme-selector/theme-selector.service'
import MapLibreLayer from '@/lib/ol-mapbox-layer'
import MaskLayer from '@/lib/ol-mask-layer'
import StylePanel from '@/components/style-selector/style-panel.vue'
import { styleUrlHelper } from '@/services/styleurl/styleurl.helper'
import { useAppStore } from '@/stores/app.store'
import { useThemeStore } from '@/stores/config.store'
import { useDrawStore } from '@/stores/draw.store'
import { clearLayersCache } from '@/stores/layers.cache'

import { useLocationInfoStore } from '@/stores/location-info.store'
import { useMapStore } from '@/stores/map.store'
import { useStyleStore } from '@/stores/style.store'
import { useUserManagerStore } from '@/stores/user-manager.store'
import i18next, { InitOptions } from 'i18next'
import backend from 'i18next-http-backend'
import I18NextVue from 'i18next-vue'
import formatMeasureDirective from '@/directives/format-measure.directive'

import App from '../App.vue'
import ProfileDraw from './components/profile_v3/profile-draw_v3.vue'
import ProfileInfos from './components/profile_v3/profile-infos_v3.vue'
import ProfileMeasures from './components/profile_v3/profile-measures_v3.vue'
import ProfileRouting from './components/profile_v3/profile-routing_v3.vue'
import { useProfileDrawv3Store } from './stores/profile-draw_v3.store'
import { useProfileInfosv3Store } from './stores/profile-infos_v3.store'
import { useProfileMeasuresv3Store } from './stores/profile-measures_v3.store'
import { useProfileRoutingv3Store } from './stores/profile-routing_v3.store'

type LuxLibOptions = {
i18nextConfig?: InitOptions
Expand Down Expand Up @@ -127,68 +118,68 @@ export default function useLuxLib(options: LuxLibOptions) {
}

export {
AlertNotifications,
App,
AuthForm,
backend,
BackgroundSelector,
clearLayersCache,
createApp,
createPinia,
defineCustomElement,
DropdownList,
FooterBar,
getCurrentInstance,
h,
App,
HeaderBar,
i18next,
getCurrentInstance,
defineCustomElement,
createPinia,
storeToRefs,
watch,
backend,
VueDOMPurifyHTML,
I18NextVue,
AlertNotifications,
AuthForm,
DropdownList,
MapContainer,
BackgroundSelector,
RemoteLayers,
LayerMetadata,
HeaderBar,
ProfileDraw,
ProfileMeasures,
ProfileRouting,
ProfileInfos,
FooterBar,
ToolbarDraw,
layerMetadataService,
LayerPanel,
LegendsPanel,
LocationInfoPanel,
SliderComparator,
MapContainer,
MapLibreLayer,
MaskLayer,
ProfileDraw,
ProfileInfos,
ProfileMeasures,
ProfileRouting,
proxyUrlHelper,
RemoteLayers,
SliderComparator,
statePersistorAppService,
statePersistorBgLayerService,
statePersistorLayersService,
statePersistorMyMapService,
statePersistorStyleService,
statePersistorThemeService,
storageHelper,
storeToRefs,
StylePanel,
styleUrlHelper,
themeSelectorService,
ToolbarDraw,
useAppStore,
useBackgroundLayer,
useDrawStore,
useLayers,
useLocationInfoStore,
useMap,
useMapStore,
useMvtStyles,
useOpenLayers,
useThemes,
useOffline,
useOfflineLayers,
useAppStore,
useBackgroundLayer,
useMapStore,
useOpenLayers,
useProfileDrawv3Store,
useProfileInfosv3Store,
useProfileMeasuresv3Store,
useProfileRoutingv3Store,
useProfileInfosv3Store,
useDrawStore,
useLocationInfoStore,
useStyleStore,
useThemes,
useThemeStore,
useUserManagerStore,
layerMetadataService,
statePersistorBgLayerService,
statePersistorLayersService,
statePersistorThemeService,
statePersistorAppService,
statePersistorStyleService,
statePersistorMyMapService,
themeSelectorService,
storageHelper,
MapLibreLayer,
MaskLayer,
StylePanel,
clearLayersCache,
VueDOMPurifyHTML,
watch,
}
40 changes: 36 additions & 4 deletions src/components/footer/toolbar-print.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,26 @@ import { Mask } from '@/lib/ol-mask-layer'
import { PRINT_FORMAT, printService } from '@/services/print.service'
import { useAlertNotificationsStore } from '@/stores/alert-notifications.store'
import { AlertNotificationType } from '@/stores/alert-notifications.store.model'
import { useAppStore } from '@/stores/app.store'
import { useTranslation } from 'i18next-vue'
import { FrameState } from 'ol/PluggableMap'
import { v4 as uuidv4 } from 'uuid'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
const { url, startPolling } = useJobStatus()
const { url, startPolling, error } = useJobStatus()
const { addNotification } = useAlertNotificationsStore()
const { t } = useTranslation()
const { lang } = useAppStore()
const uuid = uuidv4()
let framestate: FrameState | null = null
const map = useMap().getOlMap()
const mask = new Mask({ id: 'mask', opacity: 0 })
const title = ref<string>('')
const legend = ref<boolean>(false)
const layout = ref<string>('')
const layouts = computed(() =>
printService.getLayouts().map(layout => ({
Expand All @@ -45,14 +52,28 @@ const scales = computed(() =>
)
const changeScale = (value: string) => {
scalePlaceholder.value = value
scale.value = value
mask.setScale(parseInt(value, 10))
map.render()
}
const scalePlaceholder = ref<string>('')
const print = async (format: PRINT_FORMAT) => {
try {
const pollingURL = await printService.print(format)
const pollingURL = await printService.print(
{
format,
layout: layout.value,
scale: parseInt(scale.value, 10),
resolution: map.getView().getResolution()!,
title: title.value,
legend: legend.value,
lang,
t,
framestate,
},
map
)
startPolling(pollingURL)
} catch {
addNotification(
Expand All @@ -62,11 +83,22 @@ const print = async (format: PRINT_FORMAT) => {
}
}
watch(error, error => {
if (error) {
addNotification(
t('An error occurred while printing'),
AlertNotificationType.ERROR
)
}
})
watch(url, downloadURL => downloadURL && window.open(downloadURL, '_blank'))
onMounted(() => {
map.addLayer(mask)
mask.setOpacity(0.5)
map.on('rendercomplete', e => {
framestate = e.frameState || null
})
// Initial values
changeLayout(layouts.value[0].value)
Expand Down Expand Up @@ -94,7 +126,7 @@ onUnmounted(() => {
<input
class="cursor-pointer w-full p-2 lux-input"
type="text"
value=""
v-model="title"
:placeholder="t('Title', { ns: 'client' })"
data-cy="printTitle"
/>
Expand All @@ -105,7 +137,7 @@ onUnmounted(() => {
:id="uuid"
class="cursor-pointer"
type="checkbox"
value=""
v-model="legend"
data-cy="printWithLegend"
/>
<label class="font-bold block lux-text-default" :for="uuid">
Expand Down
Loading

0 comments on commit 112fa65

Please sign in to comment.