diff --git a/backend/src/api/admin.rs b/backend/src/api/admin.rs index a6fd77b..5e06911 100644 --- a/backend/src/api/admin.rs +++ b/backend/src/api/admin.rs @@ -206,7 +206,7 @@ async fn admin_login( delete, path = "/api/admin/session", responses( - (status = 200, description = "Logout", headers(("Set-Cookie" = CookieJar, description = "Cookie jar cleaned"))), + (status = 200, description = "Logout"), (status = 404, description = "User or password not found", body = ErrorResponse), ) )] diff --git a/backend/src/api/admin/categories.rs b/backend/src/api/admin/categories.rs index 31d6f81..f90417b 100644 --- a/backend/src/api/admin/categories.rs +++ b/backend/src/api/admin/categories.rs @@ -86,8 +86,7 @@ pub async fn admin_category_update( #[utoipa::path( put, - path = "/api/admin/categories/:id/icon", - request_body = Icon, + path = "/api/admin/categories/{id}/icon", params( ("id" = Uuid, Path, description = "Category identifier") ), @@ -145,7 +144,7 @@ pub async fn admin_category_delete( #[utoipa::path( delete, - path = "/api/admin/categories/:id/icon", + path = "/api/admin/categories/{id}/icon", params( ("id" = Uuid, Path, description = "Category identifier") ), diff --git a/backend/src/api/admin/entities.rs b/backend/src/api/admin/entities.rs index 4f1d756..25ff9ec 100644 --- a/backend/src/api/admin/entities.rs +++ b/backend/src/api/admin/entities.rs @@ -41,6 +41,7 @@ pub struct AdminEntityWithRelations { pub display_name: String, pub category_id: Uuid, pub family_id: Uuid, + #[schema(value_type = Object)] pub locations: sqlx::types::Json>, pub data: Value, pub tags: Vec, @@ -63,7 +64,7 @@ pub struct AdminEntityWithRelations { ("page_size" = i64, Query, description = "Number of items per page (default: 20)") ), responses( - (status = 200, description = "Search results for entities", body = AdminCachedEntitiesWithPagination), + (status = 200, description = "Search results for entities", body = PaginatedVec), (status = 401, description = "Invalid permissions", body = ErrorResponse), ) )] diff --git a/backend/src/api/admin/families.rs b/backend/src/api/admin/families.rs index 6f5717b..066347f 100644 --- a/backend/src/api/admin/families.rs +++ b/backend/src/api/admin/families.rs @@ -96,8 +96,7 @@ pub async fn admin_family_update( #[utoipa::path( put, - path = "/api/admin/families/:id/icon", - request_body = Icon, + path = "/api/admin/families/{id}/icon", params( ("id" = Uuid, Path, description = "Family identifier") ), @@ -165,7 +164,7 @@ pub async fn admin_family_delete( #[utoipa::path( delete, - path = "/api/admin/families/:id/icon", + path = "/api/admin/families/{id}/icon", params( ("id" = Uuid, Path, description = "Family identifier") ), diff --git a/backend/src/api/admin/statistics.rs b/backend/src/api/admin/statistics.rs index 6b6c23e..e38b179 100644 --- a/backend/src/api/admin/statistics.rs +++ b/backend/src/api/admin/statistics.rs @@ -21,7 +21,7 @@ pub async fn admin_home_stats( get, path = "/api/admin/stats/count-comments-entities", responses( - (status = 200, description = "Dicts of entities and comments counts by family and category id", body = Json), + (status = 200, description = "Dicts of entities and comments counts by family and category id"), (status = 401, description = "Invalid permissions", body = ErrorResponse), ) )] diff --git a/backend/src/api/admin/users.rs b/backend/src/api/admin/users.rs index eeeda42..67e3f13 100644 --- a/backend/src/api/admin/users.rs +++ b/backend/src/api/admin/users.rs @@ -30,7 +30,7 @@ pub async fn admin_users_list( #[utoipa::path( post, path = "/api/admin/users", - request_body = NewUser, + request_body = NewOrUpdatedUser, responses( (status = 200, description = "User", body = User), (status = 401, description = "Invalid permissions", body = ErrorResponse), diff --git a/backend/src/api/map.rs b/backend/src/api/map.rs index 2058f4a..cd71968 100644 --- a/backend/src/api/map.rs +++ b/backend/src/api/map.rs @@ -242,7 +242,7 @@ impl Display for SearchRequest { path = "/api/map/search", request_body = SearchRequest, responses( - (status = 200, description = "List of entities", body = CachedEntitiesWithPagination), + (status = 200, description = "List of entities", body = PaginatedVec), (status = 401, description = "Invalid token", body = ErrorResponse), ) )] diff --git a/backend/src/doc.rs b/backend/src/doc.rs index 3f369de..df0fa5b 100644 --- a/backend/src/doc.rs +++ b/backend/src/doc.rs @@ -6,7 +6,7 @@ use crate::{ AdminUserIdentity, LoginRequest, LoginResponse, }, map::{ - self, FetchedEntity, NewCommentRequest, PublicNewEntityRequest, + self, FetchEntityRequest, FetchedEntity, NewCommentRequest, PublicNewEntityRequest, PublicNewEntityResponse, SearchRequest as MapSearchRequest, ViewRequest, }, root::{self, BootstrapResponse, SafeMode, StatusResponse}, @@ -28,8 +28,8 @@ use crate::{ }, entity_cache::{ AdminCachedEntitiesWithPagination, AdminCachedEntity, Cluster, EntitiesAndClusters, - LocationRepresentation, ParentRepresentation, ViewerCachedEntitiesWithPagination, - ViewerCachedEntity, ViewerSearchedCachedEntity, + LocationRepresentation, PaginatedVec, ParentRepresentation, + ViewerCachedEntitiesWithPagination, ViewerCachedEntity, ViewerSearchedCachedEntity, }, family::{Family, Field, FieldType, Form, NewOrUpdateFamily}, options::{ @@ -159,6 +159,8 @@ use utoipa::OpenApi; PublicEntity, PublicListedEntity, PublicNewEntity, + PaginatedVec, + PaginatedVec, ViewerCachedEntity, ViewerSearchedCachedEntity, LocationRepresentation, @@ -193,6 +195,7 @@ use utoipa::OpenApi; MapSearchRequest, NewCommentRequest, PublicNewEntityRequest, + FetchEntityRequest, FetchedEntity, // helper postgis polygons MultiPolygon, diff --git a/backend/src/helpers/postgis_polygons.rs b/backend/src/helpers/postgis_polygons.rs index 10fa0a4..eb8a0e1 100644 --- a/backend/src/helpers/postgis_polygons.rs +++ b/backend/src/helpers/postgis_polygons.rs @@ -1,11 +1,8 @@ use serde::{Deserialize, Serialize}; use utoipa::ToSchema; -pub type Coordinates = (f64, f64); -pub type Polygon = Vec; - #[derive(Serialize, Deserialize, Debug, Clone, ToSchema)] -pub struct MultiPolygon(Vec); +pub struct MultiPolygon(Vec>); impl MultiPolygon { pub fn to_polygon_string(&self, srid: Option) -> String { diff --git a/backend/src/models/access_token.rs b/backend/src/models/access_token.rs index e50ba2b..d16fb15 100644 --- a/backend/src/models/access_token.rs +++ b/backend/src/models/access_token.rs @@ -55,6 +55,7 @@ pub struct PermissionPolicy { pub struct NewOrUpdateAccessToken { pub title: String, pub token: String, + #[schema(value_type = Object)] pub permissions: Json, pub active: bool, } @@ -64,6 +65,7 @@ pub struct AccessToken { pub id: Uuid, pub title: String, pub token: String, + #[schema(value_type = Object)] pub permissions: Json, pub last_week_visits: i64, pub active: bool, @@ -71,7 +73,10 @@ pub struct AccessToken { #[derive(Deserialize, Serialize, ToSchema, Debug)] pub struct AccessTokenStats { + #[schema(value_type = Object)] pub origins: Json, + + #[schema(value_type = Object)] pub visits_30_days: Json, } diff --git a/backend/src/models/entity.rs b/backend/src/models/entity.rs index 4196c76..90cf869 100644 --- a/backend/src/models/entity.rs +++ b/backend/src/models/entity.rs @@ -40,10 +40,13 @@ pub struct PublicEntity { pub display_name: String, pub category_id: Uuid, pub family_id: Uuid, + #[schema(value_type = Object)] pub locations: Json>, pub data: Value, pub tags: Vec, + #[schema(value_type = Object)] pub entity_form: Json
, + #[schema(value_type = Object)] pub comment_form: Json, pub created_at: chrono::NaiveDateTime, pub updated_at: chrono::NaiveDateTime, @@ -193,6 +196,7 @@ impl PublicEntity { pub struct AdminNewOrUpdateEntity { pub display_name: String, pub category_id: Uuid, + #[schema(value_type = Object)] pub locations: Json>, pub data: Value, pub tags: Vec, @@ -220,6 +224,7 @@ pub struct AdminEntity { pub display_name: String, pub category_id: Uuid, pub family_id: Uuid, + #[schema(value_type = Object)] pub locations: Json>, pub data: Value, pub tags: Vec, diff --git a/backend/src/models/entity_cache.rs b/backend/src/models/entity_cache.rs index 358cb3b..1c0402f 100644 --- a/backend/src/models/entity_cache.rs +++ b/backend/src/models/entity_cache.rs @@ -148,7 +148,9 @@ impl From> for AdminCachedEntitiesWithPagination #[derive(Deserialize, Serialize, ToSchema, Debug)] pub struct PaginatedVec { + #[schema(value_type = Object)] pub entities: Vec, + pub total_results: i64, pub total_pages: i64, pub response_current_page: i64, diff --git a/backend/src/models/family.rs b/backend/src/models/family.rs index 4c8ce6f..a5d68b7 100644 --- a/backend/src/models/family.rs +++ b/backend/src/models/family.rs @@ -48,6 +48,7 @@ pub struct Field { /// only for the frontend. For instance, if the field is an enum /// use it to store possible values. If it is a SingleLineText, specify /// if it's an email, a phone number, etc... + #[schema(value_type = Object)] pub field_type_metadata: Option, /// Sets if the field is indexed (used in full text search, or constraints search) @@ -79,7 +80,9 @@ pub struct Family { pub id: Uuid, pub title: String, pub icon_hash: Option, + #[schema(value_type = Object)] pub entity_form: Json, + #[schema(value_type = Object)] pub comment_form: Json, pub sort_order: i32, pub version: i32, diff --git a/backend/src/models/statistics.rs b/backend/src/models/statistics.rs index 426a1d7..2bce73e 100644 --- a/backend/src/models/statistics.rs +++ b/backend/src/models/statistics.rs @@ -93,6 +93,7 @@ pub struct HomePageStats { pub total_visits_30_days: i64, pub total_visits_7_days: i64, + #[schema(value_type = Object)] pub visits_30_days: Json, } diff --git a/frontend/components/AppIcon.vue b/frontend/components/AppIcon.vue index 32a4e2c..7eb80ba 100644 --- a/frontend/components/AppIcon.vue +++ b/frontend/components/AppIcon.vue @@ -57,7 +57,8 @@ const iconDict: Record = { addComment: mdi.mdiCommentPlus, add: mdi.mdiPlus, delete: mdi.mdiDelete, - save: mdi.mdiUpload, + upload: mdi.mdiUpload, + download: mdi.mdiDownload, lightDark: mdi.mdiThemeLightDark, loading: mdi.mdiLoading, eye: mdi.mdiEye, diff --git a/frontend/components/admin/Sidebar.vue b/frontend/components/admin/Sidebar.vue index 1a0a3d8..1c12919 100644 --- a/frontend/components/admin/Sidebar.vue +++ b/frontend/components/admin/Sidebar.vue @@ -73,7 +73,8 @@ try { await state.fetchFamilies() await state.getEntitiesCommentsCounts() } -catch { +catch (e) { + console.log(e) // Do nothing } diff --git a/frontend/components/admin/families/EditForm.vue b/frontend/components/admin/families/EditForm.vue index d9eff23..95c6467 100644 --- a/frontend/components/admin/families/EditForm.vue +++ b/frontend/components/admin/families/EditForm.vue @@ -530,8 +530,37 @@ const props = defineProps<{ onSaveCallback: (editedFormFields: FormField[]) => Promise<{ error: Error | undefined }> }>() -const edited_form_fields: Ref = ref(JSON.parse(JSON.stringify(props.originalFormFields))) // deep copy -edited_form_fields.value.sort((field_a, field_b) => field_a.form_weight - field_b.form_weight) +const edited_form_fields: Ref = ref([]) + +const page_count = ref(0) +const display_indexes: Ref> = ref({}) +const max_display_index = ref(0) + +function initOrResetComponent() { + edited_form_fields.value = (JSON.parse(JSON.stringify(props.originalFormFields))) // deep copy + edited_form_fields.value.sort((field_a, field_b) => field_a.form_weight - field_b.form_weight) + + page_count.value = (1 + Math.max(0, ...edited_form_fields.value.map(field => field.form_page))) + display_indexes.value = {} + max_display_index.value = 0 + + // Initialize display_indexes and max_display_index + edited_form_fields.value.forEach((field) => { + if (field.user_facing) { + display_indexes.value[field.key] = field.display_weight + max_display_index.value = Math.max(max_display_index.value, field.display_weight) + } + else { + display_indexes.value[field.key] = 'notDisplayed' + } + }) +} + +initOrResetComponent() + +watch(() => props.originalFormFields, () => { + initOrResetComponent() +}) const processingRequest = ref(false) const toast = useToast() @@ -562,21 +591,6 @@ const editEventsVisible = ref(false) const editEventsField: Ref = ref(null) const editEventsEvents = ref([]) -const page_count = ref(1 + Math.max(0, ...edited_form_fields.value.map(field => field.form_page))) -const display_indexes: Ref> = ref({}) -const max_display_index = ref(0) - -// Initialize display_indexes and max_display_index -edited_form_fields.value.forEach((field) => { - if (field.user_facing) { - display_indexes.value[field.key] = field.display_weight - max_display_index.value = Math.max(max_display_index.value, field.display_weight) - } - else { - display_indexes.value[field.key] = 'notDisplayed' - } -}) - const searchableTypes = ['SingleLineText', 'MultiLineText', 'RichText'] const filterableTypes = ['EnumSingleOption', 'EnumMultiOption'] const indexableTypes = [...searchableTypes, ...filterableTypes] diff --git a/frontend/components/admin/families/EditFormJson.vue b/frontend/components/admin/families/EditFormJson.vue new file mode 100644 index 0000000..15b67cb --- /dev/null +++ b/frontend/components/admin/families/EditFormJson.vue @@ -0,0 +1,207 @@ + + + diff --git a/frontend/lib/admin-auth-middleware.ts b/frontend/lib/admin-auth-middleware.ts index c4c170c..5cd5267 100644 --- a/frontend/lib/admin-auth-middleware.ts +++ b/frontend/lib/admin-auth-middleware.ts @@ -3,7 +3,8 @@ import type { Middleware } from 'openapi-fetch' // Openapi-fetch middleware function to check for 401 errors on admin pages and redirect to the admin login page export default function createAuthMiddleware(logout_callback: () => Promise): Middleware { return { - async onResponse(response, _options) { + async onResponse(params) { + const { response } = params if (response.status === 401 && response.url.match('/api/admin/session') == null) { await logout_callback() } diff --git a/frontend/lib/admin-state.ts b/frontend/lib/admin-state.ts index c0c2b15..24fd393 100644 --- a/frontend/lib/admin-state.ts +++ b/frontend/lib/admin-state.ts @@ -123,6 +123,7 @@ export class AppState { // Families async fetchFamilies(): Promise { this.familiesData = await this.client.listFamilies() + console.log(this.familiesData) this.familyRecord = this.familiesData.reduce((families, family) => { families[family.id] = family return families diff --git a/frontend/lib/viewer-auth-middleware.ts b/frontend/lib/viewer-auth-middleware.ts index 2c88173..6eca89c 100644 --- a/frontend/lib/viewer-auth-middleware.ts +++ b/frontend/lib/viewer-auth-middleware.ts @@ -9,13 +9,15 @@ export default function createAuthMiddleware( return { - async onRequest(request, _options) { + async onRequest(params) { + const { request } = params request.headers.set('X-SH-Plain-AccessToken', plainToken) request.headers.set('Authorization', `Bearer ${usedAuthToken}`) return request }, - async onResponse(response, _options) { + async onResponse(params) { + const { response } = params if (response.status === 401) { await onAuthError() } diff --git a/frontend/nuxt.config.ts b/frontend/nuxt.config.ts index 8a87824..df4a0d8 100644 --- a/frontend/nuxt.config.ts +++ b/frontend/nuxt.config.ts @@ -3,6 +3,7 @@ import theme from './theme.mjs' export default defineNuxtConfig({ + compatibilityDate: '2024-09-13', modules: [ '@primevue/nuxt-module', '@nuxt/eslint', @@ -40,4 +41,11 @@ export default defineNuxtConfig({ title: 'Safehaven', }, }, + vite: { + resolve: { + alias: { + ace: 'ace-builds/src-noconflict', + }, + }, + }, }) diff --git a/frontend/openapi.json b/frontend/openapi.json index fdd63a7..aa0e1e2 100644 --- a/frontend/openapi.json +++ b/frontend/openapi.json @@ -358,12 +358,12 @@ } } }, - "/api/admin/categories/:id/icon": { - "put": { + "/api/admin/categories/{id}": { + "get": { "tags": [ "admin::categories" ], - "operationId": "admin_category_update_icon", + "operationId": "admin_category_get", "parameters": [ { "name": "id", @@ -376,19 +376,16 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Icon" - } - } - }, - "required": true - }, "responses": { "200": { - "description": "Category icon updated" + "description": "Category details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Category" + } + } + } }, "401": { "description": "Invalid permissions", @@ -412,11 +409,11 @@ } } }, - "delete": { + "put": { "tags": [ "admin::categories" ], - "operationId": "admin_category_delete_icon", + "operationId": "admin_category_update", "parameters": [ { "name": "id", @@ -429,9 +426,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewOrUpdateCategory" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Category icon deletion successful" + "description": "Category updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Category" + } + } + } }, "401": { "description": "Invalid permissions", @@ -454,14 +468,12 @@ } } } - } - }, - "/api/admin/categories/{id}": { - "get": { + }, + "delete": { "tags": [ "admin::categories" ], - "operationId": "admin_category_get", + "operationId": "admin_category_delete", "parameters": [ { "name": "id", @@ -476,14 +488,7 @@ ], "responses": { "200": { - "description": "Category details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Category" - } - } - } + "description": "Category deletion successful" }, "401": { "description": "Invalid permissions", @@ -506,12 +511,14 @@ } } } - }, + } + }, + "/api/admin/categories/{id}/icon": { "put": { "tags": [ "admin::categories" ], - "operationId": "admin_category_update", + "operationId": "admin_category_update_icon", "parameters": [ { "name": "id", @@ -524,26 +531,9 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewOrUpdateCategory" - } - } - }, - "required": true - }, "responses": { "200": { - "description": "Category updated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Category" - } - } - } + "description": "Category icon updated" }, "401": { "description": "Invalid permissions", @@ -571,7 +561,7 @@ "tags": [ "admin::categories" ], - "operationId": "admin_category_delete", + "operationId": "admin_category_delete_icon", "parameters": [ { "name": "id", @@ -586,7 +576,7 @@ ], "responses": { "200": { - "description": "Category deletion successful" + "description": "Category icon deletion successful" }, "401": { "description": "Invalid permissions", @@ -956,7 +946,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AdminCachedEntitiesWithPagination" + "$ref": "#/components/schemas/PaginatedVec" } } } @@ -1343,12 +1333,12 @@ } } }, - "/api/admin/families/:id/icon": { - "put": { + "/api/admin/families/{id}": { + "get": { "tags": [ "admin::families" ], - "operationId": "admin_family_update_icon", + "operationId": "admin_family_get", "parameters": [ { "name": "id", @@ -1361,19 +1351,16 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Icon" - } - } - }, - "required": true - }, "responses": { "200": { - "description": "Family icon updated" + "description": "Family details", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Family" + } + } + } }, "401": { "description": "Invalid permissions", @@ -1397,11 +1384,11 @@ } } }, - "delete": { + "put": { "tags": [ "admin::families" ], - "operationId": "admin_family_delete_icon", + "operationId": "admin_family_update", "parameters": [ { "name": "id", @@ -1414,9 +1401,26 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewOrUpdateFamily" + } + } + }, + "required": true + }, "responses": { "200": { - "description": "Family icon deletion successful" + "description": "Family updated", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Family" + } + } + } }, "401": { "description": "Invalid permissions", @@ -1439,14 +1443,12 @@ } } } - } - }, - "/api/admin/families/{id}": { - "get": { + }, + "delete": { "tags": [ "admin::families" ], - "operationId": "admin_family_get", + "operationId": "admin_family_delete", "parameters": [ { "name": "id", @@ -1461,14 +1463,7 @@ ], "responses": { "200": { - "description": "Family details", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Family" - } - } - } + "description": "Family deleted successfully" }, "401": { "description": "Invalid permissions", @@ -1491,12 +1486,14 @@ } } } - }, + } + }, + "/api/admin/families/{id}/icon": { "put": { "tags": [ "admin::families" ], - "operationId": "admin_family_update", + "operationId": "admin_family_update_icon", "parameters": [ { "name": "id", @@ -1509,26 +1506,9 @@ } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NewOrUpdateFamily" - } - } - }, - "required": true - }, "responses": { "200": { - "description": "Family updated", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Family" - } - } - } + "description": "Family icon updated" }, "401": { "description": "Invalid permissions", @@ -1556,7 +1536,7 @@ "tags": [ "admin::families" ], - "operationId": "admin_family_delete", + "operationId": "admin_family_delete_icon", "parameters": [ { "name": "id", @@ -1571,7 +1551,7 @@ ], "responses": { "200": { - "description": "Family deleted successfully" + "description": "Family icon deletion successful" }, "401": { "description": "Invalid permissions", @@ -1790,15 +1770,7 @@ "operationId": "admin_logout", "responses": { "200": { - "description": "Logout", - "headers": { - "Set-Cookie": { - "schema": { - "$ref": "#/components/schemas/CookieJar" - }, - "description": "Cookie jar cleaned" - } - } + "description": "Logout" }, "404": { "description": "User or password not found", @@ -1851,14 +1823,7 @@ "operationId": "admin_count_comments_entities", "responses": { "200": { - "description": "Dicts of entities and comments counts by family and category id", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Json" - } - } - } + "description": "Dicts of entities and comments counts by family and category id" }, "401": { "description": "Invalid permissions", @@ -2140,7 +2105,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/NewUser" + "$ref": "#/components/schemas/NewOrUpdatedUser" } } }, @@ -2580,7 +2545,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CachedEntitiesWithPagination" + "$ref": "#/components/schemas/PaginatedVec" } } } @@ -2684,7 +2649,7 @@ "format": "int64" }, "permissions": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "title": { "type": "string" @@ -2702,10 +2667,10 @@ ], "properties": { "origins": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "visits_30_days": { - "$ref": "#/components/schemas/Json" + "type": "object" } } }, @@ -2848,7 +2813,7 @@ "format": "uuid" }, "locations": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "moderated": { "type": "boolean" @@ -2923,7 +2888,7 @@ "format": "uuid" }, "locations": { - "$ref": "#/components/schemas/sqlx.types.Json" + "type": "object" }, "moderated": { "type": "boolean" @@ -3101,7 +3066,7 @@ "type": "boolean" }, "locations": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "moderated": { "type": "boolean" @@ -3494,10 +3459,10 @@ ], "properties": { "comment_form": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "entity_form": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "icon_hash": { "type": "string", @@ -3520,6 +3485,37 @@ } } }, + "FetchEntityRequest": { + "type": "object", + "required": [ + "active_categories", + "active_required_tags", + "active_hidden_tags" + ], + "properties": { + "active_categories": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "active_hidden_tags": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "active_required_tags": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + } + } + }, "FetchedEntity": { "type": "object", "required": [ @@ -3558,6 +3554,7 @@ "key", "display_name", "field_type", + "field_type_metadata", "indexed", "privately_indexed", "mandatory", @@ -3581,8 +3578,8 @@ "$ref": "#/components/schemas/FieldType" }, "field_type_metadata": { - "description": "Used to store detail about the field that relevent\nonly for the frontend. For instance, if the field is an enum\nuse it to store possible values. If it is a SingleLineText, specify\nif it's an email, a phone number, etc...", - "nullable": true + "type": "object", + "description": "Used to store detail about the field that relevent\nonly for the frontend. For instance, if the field is an enum\nuse it to store possible values. If it is a SingleLineText, specify\nif it's an email, a phone number, etc..." }, "form_page": { "type": "integer", @@ -3727,7 +3724,7 @@ "format": "int64" }, "visits_30_days": { - "$ref": "#/components/schemas/Json" + "type": "object" } } }, @@ -3800,7 +3797,22 @@ "MultiPolygon": { "type": "array", "items": { - "$ref": "#/components/schemas/Polygon" + "type": "array", + "items": { + "type": "array", + "items": { + "allOf": [ + { + "type": "number", + "format": "double" + }, + { + "type": "number", + "format": "double" + } + ] + } + } } }, "NewCommentRequest": { @@ -3831,7 +3843,7 @@ "type": "boolean" }, "permissions": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "title": { "type": "string" @@ -3972,10 +3984,7 @@ ], "properties": { "entities": { - "type": "array", - "items": { - "$ref": "#/components/schemas/T" - } + "type": "object" }, "response_current_page": { "type": "integer", @@ -4154,7 +4163,7 @@ "format": "uuid" }, "comment_form": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "created_at": { "type": "string", @@ -4165,7 +4174,7 @@ "type": "string" }, "entity_form": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "family_id": { "type": "string", @@ -4176,7 +4185,7 @@ "format": "uuid" }, "locations": { - "$ref": "#/components/schemas/Json" + "type": "object" }, "tags": { "type": "array", diff --git a/frontend/package-lock.json b/frontend/package-lock.json index a91809c..8cb4f43 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,29 +13,32 @@ "@nuxtjs/tailwindcss": "^6.12.1", "@primevue/nuxt-module": "4.0.7", "@primevue/themes": "4.0.7", + "@types/ace": "^0.0.52", "@types/dompurify": "^3.0.5", "@types/validator": "^13.12.0", "@vueuse/core": "^11.0.3", "@vueuse/nuxt": "^11.0.3", + "ace-builds": "^1.36.2", "chart.js": "^4.4.3", "chartjs-adapter-luxon": "^1.3.1", "dompurify": "^3.1.4", "jdenticon": "^3.3.0", "luxon": "^3.4.4", "nuxt": "^3.13.1", - "ol": "^9.1.0", + "ol": "^10.1.0", "ol-contextmenu": "^5.4.0", "ol-ext": "^4.0.17", - "openapi-fetch": "^0.9.3", - "openapi-typescript": "^6.7.5", + "openapi-fetch": "^0.12.0", + "openapi-typescript": "^7.4.0", "primevue": "4.0.7", "quill": "^1.3.7", "tailwindcss-primeui": "^0.3.4", "typescript": "^5.4.3", "validator": "^13.12.0", "vue": "^3.4.21", - "vue-router": "^4.3.0", + "vue-router": "^4.4.5", "vue-tsc": "^2.1.6", + "vue3-ace-editor": "^2.2.4", "vue3-openlayers": "11.2.0" } }, @@ -2908,6 +2911,94 @@ "node": ">=12.11.0" } }, + "node_modules/@redocly/ajv": { + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-io1JpnwtIcvojV7QKDUSIuMN/ikdOUd1ReEnUnMKGfDVridQZ31J0MmIuqwuRjWDZfmvr+Q0MqCcfHM2gTivOg==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js-replace": "^1.0.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@redocly/ajv/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/@redocly/config": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.10.1.tgz", + "integrity": "sha512-H3LnKVGzOaxskwJu8pmJYwBOWjP61qOK7TuTrbafqArDVckE06fhA6l0nO4KvBbjLPjy1Al7UnlxOu23V4Nl0w==", + "license": "MIT" + }, + "node_modules/@redocly/openapi-core": { + "version": "1.25.1", + "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.25.1.tgz", + "integrity": "sha512-0YomtlwGFTzHOBo0FDhaEp36UjglEu90gdUkB9blke+t4kBXHbN95+XERmM1VUtBwF64s0U/kyoSw178i2ShIw==", + "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.11.2", + "@redocly/config": "^0.10.1", + "colorette": "^1.2.0", + "https-proxy-agent": "^7.0.4", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "lodash.isequal": "^4.5.0", + "minimatch": "^5.0.1", + "node-fetch": "^2.6.1", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=14.19.0", + "npm": ">=7.0.0" + } + }, + "node_modules/@redocly/openapi-core/node_modules/agent-base": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@redocly/openapi-core/node_modules/https-proxy-agent": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", + "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/@redocly/openapi-core/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@rollup/plugin-alias": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/@rollup/plugin-alias/-/plugin-alias-5.1.0.tgz", @@ -3489,6 +3580,11 @@ "url": "https://opencollective.com/turf" } }, + "node_modules/@types/ace": { + "version": "0.0.52", + "resolved": "https://registry.npmjs.org/@types/ace/-/ace-0.0.52.tgz", + "integrity": "sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==" + }, "node_modules/@types/dompurify": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz", @@ -4470,6 +4566,12 @@ "node": ">= 0.6" } }, + "node_modules/ace-builds": { + "version": "1.36.2", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.36.2.tgz", + "integrity": "sha512-eqqfbGwx/GKjM/EnFu4QtQ+d2NNBu84MGgxoG8R5iyFpcVeQ4p9YlTL+ZzdEJqhdkASqoqOxCSNNGyB6lvMm+A==", + "license": "BSD-3-Clause" + }, "node_modules/acorn": { "version": "8.12.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", @@ -5251,6 +5353,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "license": "MIT" + }, "node_modules/chart.js": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.4.tgz", @@ -5541,6 +5649,12 @@ "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "license": "MIT" }, + "node_modules/colorette": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", + "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", + "license": "MIT" + }, "node_modules/commander": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", @@ -6356,9 +6470,9 @@ "license": "MIT" }, "node_modules/earcut": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", - "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", + "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==", "license": "ISC" }, "node_modules/eastasianwidth": { @@ -7164,8 +7278,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/fast-diff": { "version": "1.1.2", @@ -8124,6 +8237,18 @@ "node": ">=8" } }, + "node_modules/index-to-position": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz", + "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -8532,6 +8657,15 @@ "jiti": "bin/jiti.js" } }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -9062,6 +9196,12 @@ "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", "license": "MIT" }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "license": "MIT" + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -9975,6 +10115,35 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/nitropack/node_modules/openapi-typescript": { + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-6.7.6.tgz", + "integrity": "sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.3", + "fast-glob": "^3.3.2", + "js-yaml": "^4.1.0", + "supports-color": "^9.4.0", + "undici": "^5.28.4", + "yargs-parser": "^21.1.1" + }, + "bin": { + "openapi-typescript": "bin/cli.js" + } + }, + "node_modules/nitropack/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -10802,17 +10971,18 @@ "license": "MIT" }, "node_modules/ol": { - "version": "9.2.4", - "resolved": "https://registry.npmjs.org/ol/-/ol-9.2.4.tgz", - "integrity": "sha512-bsbu4ObaAlbELMIZWnYEvX4Z9jO+OyCBshtODhDKmqYTPEfnKOX3RieCr97tpJkqWTZvyV4tS9UQDvHoCdxS+A==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ol/-/ol-10.1.0.tgz", + "integrity": "sha512-/efepydpzhFoeczA9KAN5t7G0WpFhP46ZXEfSl6JbZ7ipQZ2axpkYB2qt0qcOUlPFYMt7/XQFApH652KB08tTg==", "license": "BSD-2-Clause", "dependencies": { + "@types/rbush": "^3.0.3", "color-rgba": "^3.0.0", "color-space": "^2.0.1", - "earcut": "^2.2.3", + "earcut": "^3.0.0", "geotiff": "^2.0.7", - "pbf": "3.2.1", - "rbush": "^3.0.1" + "pbf": "4.0.1", + "rbush": "^4.0.0" }, "funding": { "type": "opencollective", @@ -10904,37 +11074,57 @@ } }, "node_modules/openapi-fetch": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.9.8.tgz", - "integrity": "sha512-zM6elH0EZStD/gSiNlcPrzXcVQ/pZo3BDvC6CDwRDUt1dDzxlshpmQnpD6cZaJ39THaSmwVCxxRrPKNM1hHrDg==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/openapi-fetch/-/openapi-fetch-0.12.0.tgz", + "integrity": "sha512-D/g5BUGiOAKqivR5s02veJ2+cMHzrkFJKberKP4Z8Vl2VhE6MMirI6wWOgpp8wlsYCRRK7CX0NCGVL/mt6l1fA==", "license": "MIT", "dependencies": { - "openapi-typescript-helpers": "^0.0.8" + "openapi-typescript-helpers": "^0.0.13" } }, "node_modules/openapi-typescript": { - "version": "6.7.6", - "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-6.7.6.tgz", - "integrity": "sha512-c/hfooPx+RBIOPM09GSxABOZhYPblDoyaGhqBkD/59vtpN21jEuWKDlM0KYTvqJVlSYjKs0tBcIdeXKChlSPtw==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/openapi-typescript/-/openapi-typescript-7.4.0.tgz", + "integrity": "sha512-u4iVuTGkzKG4rHFUMA/IFXTks9tYVQzkowZsScMOdzJSvIF10qSNySWHTwnN2fD+MEeWFAM8i1f3IUBlgS92eQ==", "license": "MIT", "dependencies": { + "@redocly/openapi-core": "^1.16.0", "ansi-colors": "^4.1.3", - "fast-glob": "^3.3.2", - "js-yaml": "^4.1.0", + "change-case": "^5.4.4", + "parse-json": "^8.1.0", "supports-color": "^9.4.0", - "undici": "^5.28.4", "yargs-parser": "^21.1.1" }, "bin": { "openapi-typescript": "bin/cli.js" + }, + "peerDependencies": { + "typescript": "^5.x" } }, "node_modules/openapi-typescript-helpers": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/openapi-typescript-helpers/-/openapi-typescript-helpers-0.0.8.tgz", - "integrity": "sha512-1eNjQtbfNi5Z/kFhagDIaIRj6qqDzhjNJKz8cmMW0CVdGwT6e1GLbAfgI0d28VTJa1A8jz82jm/4dG8qNoNS8g==", + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/openapi-typescript-helpers/-/openapi-typescript-helpers-0.0.13.tgz", + "integrity": "sha512-z44WK2e7ygW3aUtAtiurfEACohf/Qt9g6BsejmIYgEoY4REHeRzgFJmO3ium0libsuzPc145I+8lE9aiiZrQvQ==", "license": "MIT" }, + "node_modules/openapi-typescript/node_modules/parse-json": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz", + "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "index-to-position": "^0.1.2", + "type-fest": "^4.7.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/openapi-typescript/node_modules/supports-color": { "version": "9.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", @@ -10947,6 +11137,18 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/openapi-typescript/node_modules/type-fest": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.26.1.tgz", + "integrity": "sha512-yOGpmOAL7CkKe/91I5O3gPICmJNLJ1G4zFYVAsRHg7M64biSnPtRj0WNQt++bRkjYOqjWXrhnUw1utzmVErAdg==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -11210,12 +11412,11 @@ "license": "MIT" }, "node_modules/pbf": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", + "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", "license": "BSD-3-Clause", "dependencies": { - "ieee754": "^1.1.12", "resolve-protobuf-schema": "^2.1.0" }, "bin": { @@ -12058,9 +12259,9 @@ } }, "node_modules/quickselect": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz", - "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", + "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", "license": "ISC" }, "node_modules/quill": { @@ -12126,12 +12327,12 @@ } }, "node_modules/rbush": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz", - "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz", + "integrity": "sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==", "license": "MIT", "dependencies": { - "quickselect": "^2.0.0" + "quickselect": "^3.0.0" } }, "node_modules/rc9": { @@ -12493,6 +12694,20 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -14405,6 +14620,12 @@ "punycode": "^2.1.0" } }, + "node_modules/uri-js-replace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uri-js-replace/-/uri-js-replace-1.0.1.tgz", + "integrity": "sha512-W+C9NWNLFOoBI2QWDp4UT9pv65r2w5Cx+3sTYFvtMdDBxkKt1syCqsUdSFAChbEe1uK5TfS04wt/nGwmaeIQ0g==", + "license": "MIT" + }, "node_modules/urlpattern-polyfill": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", @@ -14886,9 +15107,9 @@ } }, "node_modules/vue-router": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.4.tgz", - "integrity": "sha512-3MlnDqwRwZwCQVbtVfpsU+nrNymNjnXSsQtXName5925NVC1+326VVfYH9vSrA0N13teGEo8z5x7gbRnGjCDiQ==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.5.tgz", + "integrity": "sha512-4fKZygS8cH1yCyuabAXGUAsyi1b2/o/OKgu/RUb+znIYOxPRxdkytJEx+0wGcpBE1pX6vUgh5jwWOKRGvuA/7Q==", "license": "MIT", "dependencies": { "@vue/devtools-api": "^6.6.4" @@ -14917,6 +15138,24 @@ "typescript": ">=5.0.0" } }, + "node_modules/vue-virtual-scroller/node_modules/mitt": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz", + "integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==", + "extraneous": true + }, + "node_modules/vue3-ace-editor": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/vue3-ace-editor/-/vue3-ace-editor-2.2.4.tgz", + "integrity": "sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==", + "dependencies": { + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "ace-builds": "*", + "vue": "^3" + } + }, "node_modules/vue3-openlayers": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/vue3-openlayers/-/vue3-openlayers-11.2.0.tgz", @@ -14944,58 +15183,6 @@ "vue": "^3.4.0" } }, - "node_modules/vue3-openlayers/node_modules/earcut": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/earcut/-/earcut-3.0.0.tgz", - "integrity": "sha512-41Fs7Q/PLq1SDbqjsgcY7GA42T0jvaCNGXgGtsNdvg+Yv8eIu06bxv4/PoREkZ9nMDNwnUSG9OFB9+yv8eKhDg==", - "license": "ISC" - }, - "node_modules/vue3-openlayers/node_modules/ol": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ol/-/ol-10.1.0.tgz", - "integrity": "sha512-/efepydpzhFoeczA9KAN5t7G0WpFhP46ZXEfSl6JbZ7ipQZ2axpkYB2qt0qcOUlPFYMt7/XQFApH652KB08tTg==", - "license": "BSD-2-Clause", - "dependencies": { - "@types/rbush": "^3.0.3", - "color-rgba": "^3.0.0", - "color-space": "^2.0.1", - "earcut": "^3.0.0", - "geotiff": "^2.0.7", - "pbf": "4.0.1", - "rbush": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/openlayers" - } - }, - "node_modules/vue3-openlayers/node_modules/pbf": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-4.0.1.tgz", - "integrity": "sha512-SuLdBvS42z33m8ejRbInMapQe8n0D3vN/Xd5fmWM3tufNgRQFBpaW2YVJxQZV4iPNqb0vEFvssMEo5w9c6BTIA==", - "license": "BSD-3-Clause", - "dependencies": { - "resolve-protobuf-schema": "^2.1.0" - }, - "bin": { - "pbf": "bin/pbf" - } - }, - "node_modules/vue3-openlayers/node_modules/quickselect": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", - "integrity": "sha512-XdjUArbK4Bm5fLLvlm5KpTFOiOThgfWWI4axAZDWg4E/0mKdZyI9tNEfds27qCi1ze/vwTR16kvmmGhRra3c2g==", - "license": "ISC" - }, - "node_modules/vue3-openlayers/node_modules/rbush": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/rbush/-/rbush-4.0.1.tgz", - "integrity": "sha512-IP0UpfeWQujYC8Jg162rMNc01Rf0gWMMAb2Uxus/Q0qOFw4lCcq6ZnQEZwUoJqWyUGJ9th7JjwI4yIWo+uvoAQ==", - "license": "MIT", - "dependencies": { - "quickselect": "^3.0.0" - } - }, "node_modules/web-worker": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", @@ -15168,6 +15355,12 @@ "node": ">= 14" } }, + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", + "license": "Apache-2.0" + }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 9d10074..26c0f08 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -23,23 +23,26 @@ "@vueuse/nuxt": "^11.0.3", "chart.js": "^4.4.3", "chartjs-adapter-luxon": "^1.3.1", + "@types/ace": "^0.0.52", + "ace-builds": "^1.36.2", "dompurify": "^3.1.4", "jdenticon": "^3.3.0", "luxon": "^3.4.4", "nuxt": "^3.13.1", - "ol": "^9.1.0", + "ol": "^10.1.0", "ol-contextmenu": "^5.4.0", "ol-ext": "^4.0.17", - "openapi-fetch": "^0.9.3", - "openapi-typescript": "^6.7.5", + "openapi-fetch": "^0.12.0", + "openapi-typescript": "^7.4.0", "primevue": "4.0.7", "quill": "^1.3.7", "tailwindcss-primeui": "^0.3.4", "typescript": "^5.4.3", "validator": "^13.12.0", "vue": "^3.4.21", - "vue-router": "^4.3.0", + "vue-router": "^4.4.5", "vue-tsc": "^2.1.6", - "vue3-openlayers": "11.2.0" + "vue3-openlayers": "11.2.0", + "vue3-ace-editor": "^2.2.4" } } diff --git a/frontend/pages/admin/families/[id]/entities.vue b/frontend/pages/admin/families/[id]/entities.vue index fb9cdea..15df2f8 100644 --- a/frontend/pages/admin/families/[id]/entities.vue +++ b/frontend/pages/admin/families/[id]/entities.vue @@ -1,5 +1,5 @@