feat(admin): implement delete functionality for Falukant regions and update UI components
This commit is contained in:
@@ -262,10 +262,35 @@
|
||||
"distances": "Entfernungen"
|
||||
},
|
||||
"regionList": "Regionen",
|
||||
"mapArea": "Karten-Arbeitsbereich",
|
||||
"selectedRegion": "Ausgewählte Region",
|
||||
"selectRegionHint": "Wähle eine Region aus der Liste oder direkt auf der Karte aus.",
|
||||
"unknownType": "Unbekannter Typ",
|
||||
"coordsCompact": "X {x}, Y {y} · B {w} × H {h}",
|
||||
"noCoords": "Keine Koordinaten gesetzt",
|
||||
"positionSet": "Position gesetzt",
|
||||
"coordinateX": "X-Position",
|
||||
"coordinateY": "Y-Position",
|
||||
"coordinateWidth": "Breite",
|
||||
"coordinateHeight": "Höhe",
|
||||
"currentRect": "Aktuelles Rechteck",
|
||||
"hintDraw": "Wähle eine Region und ziehe mit der Maus ein Rechteck auf der Karte, um die Position festzulegen.",
|
||||
"saveAll": "Alle geänderten Regionen speichern",
|
||||
"saving": "Speichere…",
|
||||
"saveSuccess": "Region wurde gespeichert.",
|
||||
"saveAllSuccess": "Alle Änderungen wurden gespeichert.",
|
||||
"errorSave": "Die Region konnte nicht gespeichert werden.",
|
||||
"unsaved": "Nicht gespeichert",
|
||||
"deleteRegion": "Region löschen",
|
||||
"deleting": "Lösche…",
|
||||
"deleteHint": "Das Löschen ist nur möglich, wenn keine Unterregionen oder Entfernungen vorhanden sind.",
|
||||
"confirmDeleteRegion": "Region „{name}“ wirklich löschen? Dieser Vorgang kann nicht rückgängig gemacht werden.",
|
||||
"deleteSuccess": "Region wurde gelöscht.",
|
||||
"deleteError": "Die Region konnte nicht gelöscht werden.",
|
||||
"deleteBlockedChildren": "Diese Region kann nicht gelöscht werden, weil sie Unterregionen enthält.",
|
||||
"deleteBlockedDistances": "Diese Region kann nicht gelöscht werden, weil sie in Entfernungsverbindungen verwendet wird.",
|
||||
"deleteBlockedInUse": "Diese Region kann nicht gelöscht werden, weil sie bereits von Spiel- oder Wetterdaten verwendet wird.",
|
||||
"deleteBlockedNotFound": "Die Region wurde bereits gelöscht oder existiert nicht mehr.",
|
||||
"createRegion": {
|
||||
"title": "Neue Region anlegen",
|
||||
"type": "Regionstyp",
|
||||
@@ -276,7 +301,8 @@
|
||||
"name": "Name",
|
||||
"create": "Region anlegen",
|
||||
"creating": "Lege an…",
|
||||
"error": "Region konnte nicht angelegt werden."
|
||||
"error": "Region konnte nicht angelegt werden.",
|
||||
"success": "Region wurde angelegt."
|
||||
},
|
||||
"connectionsTitle": "Verbindungen (region_distance)",
|
||||
"source": "Von",
|
||||
|
||||
@@ -317,10 +317,35 @@
|
||||
"distances": "Distances"
|
||||
},
|
||||
"regionList": "Regions",
|
||||
"mapArea": "Map workspace",
|
||||
"selectedRegion": "Selected region",
|
||||
"selectRegionHint": "Select a region from the list or directly on the map.",
|
||||
"unknownType": "Unknown type",
|
||||
"coordsCompact": "X {x}, Y {y} · W {w} × H {h}",
|
||||
"noCoords": "No coordinates set",
|
||||
"positionSet": "Position set",
|
||||
"coordinateX": "X position",
|
||||
"coordinateY": "Y position",
|
||||
"coordinateWidth": "Width",
|
||||
"coordinateHeight": "Height",
|
||||
"currentRect": "Current rectangle",
|
||||
"hintDraw": "Select a region and drag a rectangle on the map to set its position.",
|
||||
"saveAll": "Save all changed regions",
|
||||
"saving": "Saving…",
|
||||
"saveSuccess": "Region saved.",
|
||||
"saveAllSuccess": "All changes saved.",
|
||||
"errorSave": "Could not save the region.",
|
||||
"unsaved": "Unsaved",
|
||||
"deleteRegion": "Delete region",
|
||||
"deleting": "Deleting…",
|
||||
"deleteHint": "Deletion is available only when the region has no child regions or distance connections.",
|
||||
"confirmDeleteRegion": "Delete region “{name}”? This cannot be undone.",
|
||||
"deleteSuccess": "Region deleted.",
|
||||
"deleteError": "Could not delete the region.",
|
||||
"deleteBlockedChildren": "This region cannot be deleted because it has child regions.",
|
||||
"deleteBlockedDistances": "This region cannot be deleted because it is used by distance connections.",
|
||||
"deleteBlockedInUse": "This region cannot be deleted because it is already used by game or weather data.",
|
||||
"deleteBlockedNotFound": "This region has already been deleted or no longer exists.",
|
||||
"createRegion": {
|
||||
"title": "Create new region",
|
||||
"type": "Region type",
|
||||
@@ -331,7 +356,8 @@
|
||||
"name": "Name",
|
||||
"create": "Create region",
|
||||
"creating": "Creating…",
|
||||
"error": "Could not create region."
|
||||
"error": "Could not create region.",
|
||||
"success": "Region created."
|
||||
},
|
||||
"connectionsTitle": "Connections (region_distance)",
|
||||
"source": "From",
|
||||
|
||||
@@ -6,13 +6,18 @@
|
||||
</div>
|
||||
|
||||
<div class="map-layout">
|
||||
<div
|
||||
class="map-container"
|
||||
@mousedown="onMouseDown"
|
||||
@mousemove="onMouseMove"
|
||||
@mouseup="onMouseUp"
|
||||
@mouseleave="onMouseUp"
|
||||
>
|
||||
<section class="map-workspace" :aria-label="$t('admin.falukant.map.mapArea')">
|
||||
<div class="map-instruction">
|
||||
<span class="instruction-marker" aria-hidden="true">1</span>
|
||||
{{ $t('admin.falukant.map.hintDraw') }}
|
||||
</div>
|
||||
<div
|
||||
class="map-container"
|
||||
@mousedown="onMouseDown"
|
||||
@mousemove="onMouseMove"
|
||||
@mouseup="onMouseUp"
|
||||
@mouseleave="onMouseUp"
|
||||
>
|
||||
<img
|
||||
ref="mapImage"
|
||||
src="/images/falukant/map.png"
|
||||
@@ -39,24 +44,26 @@
|
||||
class="region-rect drawing"
|
||||
:style="rectStyle(drawingRect)"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="sidebar">
|
||||
<aside class="sidebar">
|
||||
<h2>{{ $t('admin.falukant.map.regionList') }}</h2>
|
||||
<ul class="region-list">
|
||||
<li
|
||||
v-for="region in regions"
|
||||
:key="region.id"
|
||||
:class="regionListClasses(region)"
|
||||
@click="selectRegion(region)"
|
||||
>
|
||||
{{ region.name }}
|
||||
<span v-if="region.map" class="coords">
|
||||
({{ region.map.x }},{{ region.map.y }} {{ region.map.w }}×{{ region.map.h }})
|
||||
</span>
|
||||
<span v-else class="coords missing">
|
||||
{{ $t('admin.falukant.map.noCoords') }}
|
||||
</span>
|
||||
<button type="button" class="region-list-entry" @click="selectRegion(region)">
|
||||
<span class="region-list-name">{{ region.name }}</span>
|
||||
<span class="type-badge">{{ regionTypeName(region) }}</span>
|
||||
<span v-if="region.map" class="coords">
|
||||
{{ $t('admin.falukant.map.coordsCompact', { x: region.map.x, y: region.map.y, w: region.map.w, h: region.map.h }) }}
|
||||
</span>
|
||||
<span v-else class="coords missing">{{ $t('admin.falukant.map.noCoords') }}</span>
|
||||
<span v-if="dirtyRegionIds.includes(region.id)" class="unsaved-badge">{{ $t('admin.falukant.map.unsaved') }}</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -115,34 +122,42 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div v-if="selectedRegion" class="details">
|
||||
<h3>{{ selectedRegion.name }}</h3>
|
||||
<p v-if="selectedRegion.map">
|
||||
{{ $t('admin.falukant.map.currentRect') }}:
|
||||
{{ selectedRegion.map.x }},{{ selectedRegion.map.y }}
|
||||
{{ selectedRegion.map.w }}×{{ selectedRegion.map.h }}
|
||||
</p>
|
||||
<p v-else>
|
||||
{{ $t('admin.falukant.map.noCoords') }}
|
||||
</p>
|
||||
<p class="hint">
|
||||
{{ $t('admin.falukant.map.hintDraw') }}
|
||||
</p>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
:disabled="!selectedRegionDirty"
|
||||
@click="saveSelectedRegion"
|
||||
>
|
||||
{{ $t('common.save') }}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
:disabled="!dirtyRegionIds.length"
|
||||
@click="saveAllRegions"
|
||||
>
|
||||
{{ $t('admin.falukant.map.saveAll') }}
|
||||
</button>
|
||||
</div>
|
||||
<section v-if="selectedRegion" class="details" :aria-label="$t('admin.falukant.map.selectedRegion')">
|
||||
<div class="detail-heading">
|
||||
<div>
|
||||
<p class="eyebrow">{{ $t('admin.falukant.map.selectedRegion') }}</p>
|
||||
<h3>{{ selectedRegion.name }}</h3>
|
||||
</div>
|
||||
<span class="type-badge">{{ regionTypeName(selectedRegion) }}</span>
|
||||
</div>
|
||||
<div class="selection-state">
|
||||
<span :class="['position-status', { missing: !selectedRegion.map }]">
|
||||
{{ selectedRegion.map ? $t('admin.falukant.map.positionSet') : $t('admin.falukant.map.noCoords') }}
|
||||
</span>
|
||||
<span v-if="selectedRegionDirty" class="unsaved-badge">{{ $t('admin.falukant.map.unsaved') }}</span>
|
||||
</div>
|
||||
<dl v-if="selectedRegion.map" class="coordinates-grid">
|
||||
<div><dt>{{ $t('admin.falukant.map.coordinateX') }}</dt><dd>{{ selectedRegion.map.x }}</dd></div>
|
||||
<div><dt>{{ $t('admin.falukant.map.coordinateY') }}</dt><dd>{{ selectedRegion.map.y }}</dd></div>
|
||||
<div><dt>{{ $t('admin.falukant.map.coordinateWidth') }}</dt><dd>{{ selectedRegion.map.w }}</dd></div>
|
||||
<div><dt>{{ $t('admin.falukant.map.coordinateHeight') }}</dt><dd>{{ selectedRegion.map.h }}</dd></div>
|
||||
</dl>
|
||||
<div class="detail-actions">
|
||||
<button class="btn btn-primary" :disabled="!selectedRegionDirty || savingRegion" @click="saveSelectedRegion">
|
||||
{{ savingRegion ? $t('admin.falukant.map.saving') : $t('common.save') }}
|
||||
</button>
|
||||
<button class="btn btn-secondary" :disabled="!dirtyRegionIds.length || savingAllRegions" @click="saveAllRegions">
|
||||
{{ savingAllRegions ? $t('admin.falukant.map.saving') : $t('admin.falukant.map.saveAll') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="danger-zone">
|
||||
<span>{{ $t('admin.falukant.map.deleteHint') }}</span>
|
||||
<button class="btn btn-danger" :disabled="deletingRegion" @click="deleteSelectedRegion">
|
||||
{{ deletingRegion ? $t('admin.falukant.map.deleting') : $t('admin.falukant.map.deleteRegion') }}
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
<p v-else class="empty-selection">{{ $t('admin.falukant.map.selectRegionHint') }}</p>
|
||||
</div>
|
||||
|
||||
<div v-else-if="activeTab === 'distances'" class="connections">
|
||||
@@ -261,7 +276,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -269,7 +284,7 @@
|
||||
<script>
|
||||
import apiClient from '@/utils/axios.js';
|
||||
import SimpleTabs from '@/components/SimpleTabs.vue';
|
||||
import { confirmAction, showError } from '@/utils/feedback.js';
|
||||
import { confirmAction, showError, showSuccess } from '@/utils/feedback.js';
|
||||
|
||||
export default {
|
||||
name: 'AdminFalukantMapRegionsView',
|
||||
@@ -306,6 +321,9 @@ export default {
|
||||
},
|
||||
creatingRegion: false,
|
||||
createRegionError: null,
|
||||
savingRegion: false,
|
||||
savingAllRegions: false,
|
||||
deletingRegion: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -375,6 +393,10 @@ export default {
|
||||
}
|
||||
return raw;
|
||||
},
|
||||
regionTypeName(region) {
|
||||
return this.regionTypeLabel(region?.regionType?.labelTr)
|
||||
|| this.$t('admin.falukant.map.unknownType');
|
||||
},
|
||||
async loadRegions() {
|
||||
try {
|
||||
const { data } = await apiClient.get('/api/admin/falukant/regions/all');
|
||||
@@ -422,6 +444,7 @@ export default {
|
||||
if (this.parentRegionEnabled) {
|
||||
this.newRegion.parentId = null;
|
||||
}
|
||||
showSuccess(this, this.$t('admin.falukant.map.createRegion.success'));
|
||||
} catch (error) {
|
||||
console.error('Error creating region:', error);
|
||||
const errKey = error?.response?.data?.error;
|
||||
@@ -577,6 +600,7 @@ export default {
|
||||
},
|
||||
async saveSelectedRegion() {
|
||||
if (!this.selectedRegion || !this.selectedRegion.map) return;
|
||||
this.savingRegion = true;
|
||||
try {
|
||||
await this.saveRegion(this.selectedRegion);
|
||||
// Liste aktualisieren, damit andere Einträge auch aktualisierte Daten sehen
|
||||
@@ -585,12 +609,17 @@ export default {
|
||||
if (refreshed) {
|
||||
this.selectedRegion = refreshed;
|
||||
}
|
||||
showSuccess(this, this.$t('admin.falukant.map.saveSuccess'));
|
||||
} catch (error) {
|
||||
console.error('Error saving region map:', error);
|
||||
showError(this, this.$t('admin.falukant.map.errorSave'));
|
||||
} finally {
|
||||
this.savingRegion = false;
|
||||
}
|
||||
},
|
||||
async saveAllRegions() {
|
||||
if (!this.dirtyRegionIds.length) return;
|
||||
this.savingAllRegions = true;
|
||||
try {
|
||||
const dirtyIds = [...this.dirtyRegionIds];
|
||||
for (const id of dirtyIds) {
|
||||
@@ -605,8 +634,45 @@ export default {
|
||||
this.selectedRegion = refreshed;
|
||||
}
|
||||
}
|
||||
showSuccess(this, this.$t('admin.falukant.map.saveAllSuccess'));
|
||||
} catch (error) {
|
||||
console.error('Error saving all region maps:', error);
|
||||
showError(this, this.$t('admin.falukant.map.errorSave'));
|
||||
} finally {
|
||||
this.savingAllRegions = false;
|
||||
}
|
||||
},
|
||||
async deleteSelectedRegion() {
|
||||
const region = this.selectedRegion;
|
||||
if (!region || this.deletingRegion) return;
|
||||
|
||||
const confirmed = await confirmAction(this, {
|
||||
title: this.$t('admin.falukant.map.deleteRegion'),
|
||||
message: this.$t('admin.falukant.map.confirmDeleteRegion', { name: region.name }),
|
||||
});
|
||||
if (!confirmed) return;
|
||||
|
||||
this.deletingRegion = true;
|
||||
try {
|
||||
await apiClient.delete(`/api/admin/falukant/regions/${region.id}`);
|
||||
await Promise.all([this.loadRegions(), this.loadConnections()]);
|
||||
this.selectedRegion = null;
|
||||
this.selectedRegionDirty = false;
|
||||
this.dirtyRegionIds = [];
|
||||
this.drawingRect = null;
|
||||
showSuccess(this, this.$t('admin.falukant.map.deleteSuccess'));
|
||||
} catch (error) {
|
||||
console.error('Error deleting Falukant region:', error);
|
||||
const errorKey = error?.response?.data?.error;
|
||||
const messages = {
|
||||
regionHasChildren: 'deleteBlockedChildren',
|
||||
regionHasDistances: 'deleteBlockedDistances',
|
||||
regionInUse: 'deleteBlockedInUse',
|
||||
regionNotFound: 'deleteBlockedNotFound',
|
||||
};
|
||||
showError(this, this.$t(`admin.falukant.map.${messages[errorKey] || 'deleteError'}`));
|
||||
} finally {
|
||||
this.deletingRegion = false;
|
||||
}
|
||||
},
|
||||
async saveConnection() {
|
||||
@@ -647,22 +713,58 @@ export default {
|
||||
|
||||
<style scoped>
|
||||
.falukant-map-admin {
|
||||
padding: 10px;
|
||||
padding: 12px;
|
||||
color: #24313d;
|
||||
}
|
||||
|
||||
.map-layout {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) minmax(280px, 360px);
|
||||
gap: 16px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.map-workspace {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.map-instruction {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 10px;
|
||||
border-left: 3px solid #1976d2;
|
||||
background: #f4f8fc;
|
||||
color: #41556a;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.instruction-marker {
|
||||
display: inline-grid;
|
||||
place-items: center;
|
||||
flex: 0 0 auto;
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
border-radius: 50%;
|
||||
background: #1976d2;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 0.72rem;
|
||||
}
|
||||
|
||||
.map-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
line-height: 0;
|
||||
}
|
||||
|
||||
.map {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid #bac6d0;
|
||||
}
|
||||
|
||||
.region-rect {
|
||||
@@ -673,8 +775,9 @@ export default {
|
||||
}
|
||||
|
||||
.region-rect.selected {
|
||||
border-color: rgba(255, 128, 0, 0.9);
|
||||
background-color: rgba(255, 128, 0, 0.25);
|
||||
border-color: rgba(20, 97, 173, 1);
|
||||
background-color: rgba(25, 118, 210, 0.28);
|
||||
box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.75);
|
||||
}
|
||||
|
||||
.region-rect.drawing {
|
||||
@@ -682,8 +785,10 @@ export default {
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
min-width: 260px;
|
||||
max-width: 320px;
|
||||
min-width: 0;
|
||||
padding: 12px;
|
||||
border: 1px solid #d7dee5;
|
||||
background: #fbfcfd;
|
||||
}
|
||||
|
||||
.region-list {
|
||||
@@ -692,24 +797,48 @@ export default {
|
||||
margin: 0 0 1rem 0;
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
border: 1px solid #ccc;
|
||||
border: 1px solid #cbd5df;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.region-list li {
|
||||
padding: 4px 8px;
|
||||
border-bottom: 1px solid #edf0f3;
|
||||
}
|
||||
|
||||
.region-list li:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.region-list-entry {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: 3px 8px;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: inherit;
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.region-list li:nth-child(odd) {
|
||||
background-color: #f8f8f8;
|
||||
.region-list-entry:hover,
|
||||
.region-list-entry:focus-visible {
|
||||
background: #eef6ff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.region-list li.selected {
|
||||
background-color: #e0f0ff;
|
||||
font-weight: bold;
|
||||
.region-list li.selected .region-list-entry {
|
||||
background-color: #dcecff;
|
||||
box-shadow: inset 3px 0 0 #1976d2;
|
||||
}
|
||||
|
||||
.region-list-name {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.region-rect.source,
|
||||
@@ -724,10 +853,11 @@ export default {
|
||||
}
|
||||
|
||||
.region-list li.dirty {
|
||||
font-style: italic;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
.coords {
|
||||
grid-column: 1 / -1;
|
||||
font-size: 0.8rem;
|
||||
color: #555;
|
||||
}
|
||||
@@ -737,7 +867,129 @@ export default {
|
||||
}
|
||||
|
||||
.details {
|
||||
margin-top: 1rem;
|
||||
margin-top: 12px;
|
||||
padding: 12px;
|
||||
border: 1px solid #b9d5ef;
|
||||
border-left: 3px solid #1976d2;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.detail-heading,
|
||||
.selection-state,
|
||||
.detail-actions,
|
||||
.danger-zone {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.detail-heading h3 {
|
||||
margin: 0;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
margin: 0 0 2px;
|
||||
color: #657786;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.04em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.type-badge,
|
||||
.unsaved-badge,
|
||||
.position-status {
|
||||
display: inline-block;
|
||||
width: fit-content;
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.type-badge {
|
||||
background: #e8eef4;
|
||||
color: #34495d;
|
||||
}
|
||||
|
||||
.unsaved-badge {
|
||||
background: #fff1ce;
|
||||
color: #815700;
|
||||
}
|
||||
|
||||
.position-status {
|
||||
margin-top: 10px;
|
||||
background: #eaf4ff;
|
||||
color: #1765a9;
|
||||
}
|
||||
|
||||
.position-status.missing {
|
||||
background: #f4f0e8;
|
||||
color: #6b5a39;
|
||||
}
|
||||
|
||||
.coordinates-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
gap: 1px;
|
||||
margin: 12px 0;
|
||||
background: #dfe6ec;
|
||||
}
|
||||
|
||||
.coordinates-grid > div {
|
||||
min-width: 0;
|
||||
padding: 6px;
|
||||
background: #f8fafb;
|
||||
}
|
||||
|
||||
.coordinates-grid dt {
|
||||
color: #687986;
|
||||
font-size: 0.68rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.coordinates-grid dd {
|
||||
margin: 2px 0 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-family: monospace;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.detail-actions {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.danger-zone {
|
||||
margin-top: 12px;
|
||||
padding-top: 10px;
|
||||
border-top: 1px solid #e6d8d8;
|
||||
color: #7a4a4a;
|
||||
font-size: 0.78rem;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
margin-left: auto;
|
||||
border-color: #c84646;
|
||||
background: #fff;
|
||||
color: #a52e2e;
|
||||
}
|
||||
|
||||
.btn-danger:hover:not(:disabled),
|
||||
.btn-danger:focus-visible {
|
||||
background: #c84646;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.empty-selection {
|
||||
margin: 12px 0 0;
|
||||
padding: 10px;
|
||||
border: 1px dashed #c5d0da;
|
||||
color: #627482;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.create-region {
|
||||
@@ -811,4 +1063,37 @@ export default {
|
||||
|
||||
.btn.mini.icon {
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.map-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.region-list {
|
||||
max-height: 260px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.falukant-map-admin {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.coordinates-grid {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.danger-zone {
|
||||
align-items: flex-start;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user