This commit is contained in:
commit
95efcac454
27 changed files with 700 additions and 429 deletions
8
public/assets/css/src/_global.scss
Normal file
8
public/assets/css/src/_global.scss
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
button[disabled] {
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
button[disabled]:hover {
|
||||
background-color: inherit !important;
|
||||
}
|
||||
|
|
@ -234,8 +234,8 @@ img {
|
|||
--space-m: 2rem;
|
||||
--space-big: 3em;
|
||||
--curve: cubic-bezier(0.86, 0, 0.07, 1);
|
||||
--sans-serif: "DM Sans", sans-serif;
|
||||
--mono: "Inconsolata", monospace;
|
||||
--sans-serif: 'DM Sans', sans-serif;
|
||||
--mono: 'Inconsolata', monospace;
|
||||
--input-h: 26px;
|
||||
--input-w: 160px;
|
||||
--input-w-small: 45px;
|
||||
|
|
@ -688,4 +688,13 @@ input[type=number] {
|
|||
line-height: 1.5;
|
||||
resize: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
cursor: not-allowed !important;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
button[disabled]:hover {
|
||||
background-color: inherit !important;
|
||||
}/*# sourceMappingURL=style.css.map */
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -8,3 +8,4 @@
|
|||
@use "src/_forms-section.scss" as *;
|
||||
@use "src/_buttons.scss" as *;
|
||||
@use "src/_settings-popup.scss" as *;
|
||||
@use "src/_global.scss" as *;
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 2.4 MiB |
|
|
@ -1 +1 @@
|
|||
Uuid: f9jqf7vus7w0dx6z
|
||||
Uuid: kmmswqjqh5mxyecl
|
||||
|
|
@ -15,9 +15,9 @@ Mapdata:
|
|||
background:
|
||||
type: osm
|
||||
center:
|
||||
lat: 43.82684265866453
|
||||
lon: 4.3375882121084715
|
||||
zoom: 11.37799302158894
|
||||
lat: 43.484330002696964
|
||||
lon: 4.029111008525206
|
||||
zoom: 6.503825883663738
|
||||
|
||||
----
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Customcss:
|
|||
@page {
|
||||
size: A4;
|
||||
margin: 50mm 15mm 26mm 15mm;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
background: rgb(227, 33, 33);
|
||||
}
|
||||
|
||||
body {
|
||||
|
|
@ -36,10 +36,10 @@ p {
|
|||
font-weight: 300;
|
||||
font-family: Arial;
|
||||
font-style: italic;
|
||||
padding-top: 20mm;
|
||||
padding-right: 20mm;
|
||||
padding-bottom: 20mm;
|
||||
padding-left: 20mm;
|
||||
padding-top: 0mm;
|
||||
padding-right: 0mm;
|
||||
padding-bottom: 0mm;
|
||||
padding-left: 0mm;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ columns:
|
|||
template:
|
||||
- map
|
||||
- geoformat
|
||||
info: "{{ page.intendedTemplate }}"
|
||||
sidebar:
|
||||
width: 1/3
|
||||
sections:
|
||||
|
|
|
|||
|
|
@ -7,17 +7,17 @@ columns:
|
|||
fields:
|
||||
type: fields
|
||||
fields:
|
||||
subtitle:
|
||||
subtitle:
|
||||
label: Sous-titre
|
||||
type: text
|
||||
width: 1/2
|
||||
cover:
|
||||
cover:
|
||||
label: Image de couverture
|
||||
type: files
|
||||
multiple: false
|
||||
width: 1/2
|
||||
pages:
|
||||
label: Narratives
|
||||
label: Récits
|
||||
type: pages
|
||||
template: narrative
|
||||
sidebar:
|
||||
|
|
@ -26,6 +26,3 @@ columns:
|
|||
files:
|
||||
label: Fichiers
|
||||
type: files
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -56,6 +56,7 @@ Kirby::plugin('geoproject/map-editor', [
|
|||
require __DIR__ . '/routes/markers/update.php',
|
||||
require __DIR__ . '/routes/markers/delete.php',
|
||||
require __DIR__ . '/routes/position/update.php',
|
||||
require __DIR__ . '/routes/mapdata/save.php',
|
||||
require __DIR__ . '/routes/image/capture.php',
|
||||
require __DIR__ . '/routes/image/check-flag.php',
|
||||
require __DIR__ . '/routes/image/clear-flag.php',
|
||||
|
|
|
|||
69
public/site/plugins/map-editor/routes/mapdata/save.php
Normal file
69
public/site/plugins/map-editor/routes/mapdata/save.php
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* PATCH save map data (center, zoom) directly to the page content
|
||||
*/
|
||||
|
||||
return [
|
||||
'pattern' => 'map-editor/pages/(:all)/mapdata',
|
||||
'method' => 'PATCH',
|
||||
'auth' => false,
|
||||
'action' => function (string $pageId) {
|
||||
try {
|
||||
$user = kirby()->user();
|
||||
|
||||
if (!$user && !kirby()->option('debug', false)) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'Unauthorized',
|
||||
'code' => 401
|
||||
];
|
||||
}
|
||||
|
||||
$page = kirby()->page($pageId);
|
||||
if (!$page) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'Page not found',
|
||||
'code' => 404
|
||||
];
|
||||
}
|
||||
|
||||
if (!$page->permissions()->can('update')) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'Forbidden',
|
||||
'code' => 403
|
||||
];
|
||||
}
|
||||
|
||||
$data = kirby()->request()->data();
|
||||
|
||||
if (!isset($data['mapdata'])) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'mapdata is required',
|
||||
'code' => 400
|
||||
];
|
||||
}
|
||||
|
||||
$page->update([
|
||||
'mapdata' => $data['mapdata']
|
||||
]);
|
||||
|
||||
return [
|
||||
'status' => 'success',
|
||||
'data' => [
|
||||
'message' => 'Map data saved successfully'
|
||||
]
|
||||
];
|
||||
|
||||
} catch (Exception $e) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => $e->getMessage(),
|
||||
'code' => 500
|
||||
];
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
@ -22,10 +22,11 @@
|
|||
v-if="mode === 'multi'"
|
||||
class="save-framing-button"
|
||||
type="button"
|
||||
:disabled="isCapturing"
|
||||
@click="saveCurrentFraming"
|
||||
title="Utiliser le niveau de zoom et centrage actuel comme cadrage par défaut"
|
||||
>
|
||||
Définir le cadrage
|
||||
{{ isCapturing ? 'Capture en cours…' : 'Définir le cadrage' }}
|
||||
</button>
|
||||
|
||||
<MapPreview
|
||||
|
|
@ -55,6 +56,7 @@ import {
|
|||
onBeforeUnmount,
|
||||
nextTick,
|
||||
} from 'vue';
|
||||
import yaml from 'js-yaml';
|
||||
import MapPreview from '../map/MapPreview.vue';
|
||||
import MarkerList from '../map/MarkerList.vue';
|
||||
import { useMarkersApi } from '../../composables/useMarkersApi.js';
|
||||
|
|
@ -112,6 +114,7 @@ export default {
|
|||
const mapPreview = ref(null);
|
||||
const selectedMarkerId = ref(null);
|
||||
const isInitialLoad = ref(true);
|
||||
const isCapturing = ref(false);
|
||||
|
||||
// Extract page ID from field name
|
||||
// For single mode, we don't need the API
|
||||
|
|
@ -508,10 +511,19 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// Get CSRF token (same logic as useMarkersApi)
|
||||
const getCsrfToken = () => {
|
||||
if (window.panel && window.panel.csrf) return window.panel.csrf;
|
||||
const meta = document.querySelector('meta[name="csrf"]');
|
||||
if (meta && meta.content) return meta.content;
|
||||
if (window.csrf) return window.csrf;
|
||||
return '';
|
||||
};
|
||||
|
||||
/**
|
||||
* Save current map framing (center + zoom)
|
||||
* Save current map framing (center + zoom) and capture image immediately
|
||||
*/
|
||||
function saveCurrentFraming() {
|
||||
async function saveCurrentFraming() {
|
||||
if (!mapPreview.value) return;
|
||||
|
||||
// Get current center and zoom from the map
|
||||
|
|
@ -530,8 +542,39 @@ export default {
|
|||
};
|
||||
zoom.value = currentZoom;
|
||||
|
||||
// Save immediately (not debounced)
|
||||
saveMapData();
|
||||
isCapturing.value = true;
|
||||
try {
|
||||
// Save map data directly via API (bypasses emit('input') → no draft state)
|
||||
const yamlString = yaml.dump({
|
||||
background: { type: 'osm' },
|
||||
center: { lat: center.value.lat, lon: center.value.lon },
|
||||
zoom: zoom.value,
|
||||
}, { indent: 2, lineWidth: -1, noRefs: true });
|
||||
|
||||
await fetch(`/api/map-editor/pages/${pageId.value}/mapdata`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF': getCsrfToken(),
|
||||
},
|
||||
body: JSON.stringify({ mapdata: yamlString }),
|
||||
});
|
||||
|
||||
// Capture image directly (map is already rendered)
|
||||
await captureAndSaveMapImage();
|
||||
|
||||
// Clear the regeneration flag (set by the hook after page update)
|
||||
await fetch(
|
||||
`/api/map-editor/pages/${pageId.value}/clear-regenerate-flag`,
|
||||
{ method: 'DELETE' }
|
||||
);
|
||||
|
||||
// Reload to show the new image in the panel
|
||||
window.location.reload();
|
||||
} catch (error) {
|
||||
console.error('Failed to save framing:', error);
|
||||
isCapturing.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -648,6 +691,7 @@ export default {
|
|||
mapReady,
|
||||
mapPreview,
|
||||
canAddMarker,
|
||||
isCapturing,
|
||||
loading: markersApi.loading,
|
||||
error: markersApi.error,
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue