From ea2ee2c49f49458539272ccd907d530c36520b1d Mon Sep 17 00:00:00 2001 From: Aaron Gundel Date: Mon, 13 Jan 2025 13:48:25 -0700 Subject: [PATCH] fixup! Adds note editor (#177) --- arches_lingo/src/arches_lingo/api.ts | 20 +++ .../components/generic/NoteEditor.vue | 139 ++++++++++++++---- .../components/scheme/editor/SchemeEditor.vue | 25 +++- .../components/scheme/report/SchemeNote.vue | 24 ++- arches_lingo/src/arches_lingo/constants.ts | 3 + .../src/arches_lingo/pages/SchemePage.vue | 1 + arches_lingo/templates/arches_urls.htm | 1 + arches_lingo/urls.py | 6 + arches_lingo/views/api/pythonic_models.py | 5 + 9 files changed, 180 insertions(+), 44 deletions(-) diff --git a/arches_lingo/src/arches_lingo/api.ts b/arches_lingo/src/arches_lingo/api.ts index 304d5217..52ccb3d2 100644 --- a/arches_lingo/src/arches_lingo/api.ts +++ b/arches_lingo/src/arches_lingo/api.ts @@ -104,6 +104,26 @@ export const createSchemeLabel = async ( return parsed; }; +export const createSchemeNote = async ( + schemeId: string, + statement: SchemeStatement, +) => { + const response = await fetch(arches.urls.api_scheme_note_create, { + method: "POST", + headers: { + "X-CSRFTOKEN": getToken(), + "Content-Type": "application/json", + }, + body: JSON.stringify({ + resourceinstance: schemeId, + ...statement, + }), + }); + const parsed = await response.json(); + if (!response.ok) throw new Error(parsed.message || response.statusText); + return parsed; +}; + export const deleteSchemeLabelTile = async ( schemeId: string, tileId: string, diff --git a/arches_lingo/src/arches_lingo/components/generic/NoteEditor.vue b/arches_lingo/src/arches_lingo/components/generic/NoteEditor.vue index 75c2f77f..2da0ab6e 100644 --- a/arches_lingo/src/arches_lingo/components/generic/NoteEditor.vue +++ b/arches_lingo/src/arches_lingo/components/generic/NoteEditor.vue @@ -3,10 +3,12 @@ import { computed, inject, onMounted, ref, toRaw, toRef, type Ref } from "vue"; import Button from "primevue/button"; import { useGettext } from "vue3-gettext"; -import { useRoute } from "vue-router"; +import { useRoute, useRouter } from "vue-router"; import { useToast } from "primevue/usetoast"; import { + createScheme, + createSchemeNote, fetchControlledListOptions, fetchGroupRdmSystemList, fetchPersonRdmSystemList, @@ -26,6 +28,7 @@ import { LABEL_CONTROLLED_LIST, LANGUAGE_CONTROLLED_LIST, METATYPES_CONTROLLED_LIST, + NEW, selectedLanguageKey, STATUSES_CONTROLLED_LIST, } from "@/arches_lingo/constants.ts"; @@ -35,6 +38,7 @@ import type { ControlledListItemResult, ResourceInstanceReference, ResourceInstanceResult, + SchemeInstance, SchemeStatement, } from "@/arches_lingo/types.ts"; import type { Language } from "@/arches_vue_utils/types.ts"; @@ -42,6 +46,7 @@ import type { Language } from "@/arches_vue_utils/types.ts"; const emit = defineEmits(["update"]); const toast = useToast(); const route = useRoute(); +const router = useRouter(); const selectedLanguage = inject(selectedLanguageKey) as Ref; const { $gettext } = useGettext(); @@ -62,6 +67,10 @@ const formValue = computed({ }, }); +onMounted(async () => { + initializeSelectOptions(); +}); + const languageOptions = ref([]); const typeOptions = ref([]); const statusOptions = ref([]); @@ -70,24 +79,56 @@ const eventTypeOptions = ref([]); const groupAndPersonOptions = ref(); const textualWorkOptions = ref(); -function onUpdate( +function onUpdateString(node: keyof SchemeStatement, val: string) { + (formValue.value[node] as unknown) = toRaw(val); +} + +function onUpdateReferenceDatatype( + node: keyof SchemeStatement, + val: ControlledListItem[], +) { + (formValue.value[node] as unknown) = val.map((item) => toRaw(item)); +} + +function onUpdateResourceInstance( node: keyof SchemeStatement, - val: ControlledListItem[] | ResourceInstanceReference[] | string, + val: string[], + options: ResourceInstanceReference[], ) { - if (Array.isArray(val)) { - (formValue.value[node] as unknown) = val.map((item) => toRaw(item)); - } else { - (formValue.value[node] as unknown) = toRaw(val); + if (val.length > 0) { + const selectedOptions = options.filter((option) => + val.includes(option.resourceId), + ); + (formValue.value[node] as unknown) = selectedOptions; } } async function save() { try { - await updateSchemeNote( - route.params.id as string, - formValue.value.tileid as string, - formValue.value, - ); + if (route.params.id === NEW) { + const newSchemeInstance: SchemeInstance = { + statement: [toRaw(formValue.value)], + }; + const updated = await createScheme(newSchemeInstance); + await router.push({ + name: "scheme", + params: { id: updated.resourceinstanceid }, + }); + } else if (!formValue.value.tileid) { + const schemeStatement: SchemeStatement = await createSchemeNote( + route.params.id as string, + { ...formValue.value }, + ); + valueRef.value = schemeStatement; + emit("update", schemeStatement.tileid); + return; + } else { + await updateSchemeNote( + route.params.id as string, + formValue.value.tileid, + { ...formValue.value }, + ); + } emit("update"); } catch (error) { toast.add({ @@ -128,7 +169,7 @@ async function getResourceInstanceOptions( return results; } -onMounted(async () => { +async function initializeSelectOptions() { const [languageOpts, typeOpts, statusOpts, metatypeOpts, eventTypeOpts] = await Promise.all([ getControlledListOptions(LANGUAGE_CONTROLLED_LIST), @@ -153,88 +194,122 @@ onMounted(async () => { textualWorkOptions.value = await getResourceInstanceOptions( fetchTextualWorkRdmSystemList, ); -}); +} diff --git a/arches_lingo/src/arches_lingo/components/scheme/report/SchemeNote.vue b/arches_lingo/src/arches_lingo/components/scheme/report/SchemeNote.vue index ebab9ffd..fcff21bd 100644 --- a/arches_lingo/src/arches_lingo/components/scheme/report/SchemeNote.vue +++ b/arches_lingo/src/arches_lingo/components/scheme/report/SchemeNote.vue @@ -1,5 +1,5 @@ diff --git a/arches_lingo/src/arches_lingo/constants.ts b/arches_lingo/src/arches_lingo/constants.ts index 703954f8..17544310 100644 --- a/arches_lingo/src/arches_lingo/constants.ts +++ b/arches_lingo/src/arches_lingo/constants.ts @@ -11,6 +11,9 @@ export const VIEW = "view"; export const OPEN_EDITOR = "openEditor"; export const UPDATED = "updated"; export const NEW = "new"; +export const MAXIMIZE = "maximize"; +export const SIDE = "side"; +export const CLOSE = "close"; export const DEFAULT_ERROR_TOAST_LIFE = 8000; export const SEARCH_RESULTS_PER_PAGE = 25; diff --git a/arches_lingo/src/arches_lingo/pages/SchemePage.vue b/arches_lingo/src/arches_lingo/pages/SchemePage.vue index f6eba9cc..df5eec94 100644 --- a/arches_lingo/src/arches_lingo/pages/SchemePage.vue +++ b/arches_lingo/src/arches_lingo/pages/SchemePage.vue @@ -94,6 +94,7 @@ const getRef = (el: object | null, index: number) => { @side="onSide" @close="onClose" @updated="onUpdated" + @open-editor="onOpenEditor" /> diff --git a/arches_lingo/templates/arches_urls.htm b/arches_lingo/templates/arches_urls.htm index 13f631d2..685c134b 100644 --- a/arches_lingo/templates/arches_urls.htm +++ b/arches_lingo/templates/arches_urls.htm @@ -16,6 +16,7 @@ api_scheme_label_create="{% url 'api-scheme-label-create' %}" api_scheme_note='(resourceid)=>{return "{% url "api-scheme-note" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" %}".replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", resourceid)}' api_scheme_note_tile='(resourceid, tileid)=>{return "{% url "api-scheme-note-tile" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaab" %}".replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", resourceid).replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaab", tileid)}' + api_scheme_note_create="{% url 'api-scheme-note-create' %}" api_scheme_creation='(resourceid)=>{return "{% url "api-scheme-creation" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" %}".replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", resourceid)}' api_textualwork_list="{% url 'api-textualwork-list' %}" api_group_list="{% url 'api-group-list' %}" diff --git a/arches_lingo/urls.py b/arches_lingo/urls.py index e0bdfa02..16d19f74 100644 --- a/arches_lingo/urls.py +++ b/arches_lingo/urls.py @@ -21,6 +21,7 @@ SchemeNamespaceView, SchemeNoteTileView, SchemeNoteView, + SchemeNoteCreateView, SchemeStatementDetailView, SchemeStatementListCreateView, TextualWorkRdmSystemSerializerView, @@ -86,6 +87,11 @@ SchemeNoteTileView.as_view(), name="api-scheme-note-tile", ), + path( + "api/scheme/note", + SchemeNoteCreateView.as_view(), + name="api-scheme-note-create", + ), path( "api/textual-work", TextualWorkRdmSystemSerializerView.as_view(), diff --git a/arches_lingo/views/api/pythonic_models.py b/arches_lingo/views/api/pythonic_models.py index aa3ed1d7..ccdf108f 100644 --- a/arches_lingo/views/api/pythonic_models.py +++ b/arches_lingo/views/api/pythonic_models.py @@ -85,6 +85,11 @@ class SchemeNoteTileView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView): serializer_class = SchemeNoteTileSerializer +class SchemeNoteCreateView(ArchesModelAPIMixin, ListCreateAPIView): + permission_classes = [RDMAdministrator] + serializer_class = SchemeNoteTileSerializer + + class TextualWorkRdmSystemSerializerView(ArchesModelAPIMixin, ListAPIView): permission_classes = [RDMAdministrator] serializer_class = TextualWorkRdmSystemSerializer