Skip to content

Commit

Permalink
Add schem right editor, #151
Browse files Browse the repository at this point in the history
  • Loading branch information
njkim committed Jan 9, 2025
1 parent a6399de commit 6259b4b
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 51 deletions.
9 changes: 9 additions & 0 deletions arches_lingo/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ class Meta:
nodegroups = ["rights"]
fields = "__all__"


class SchemeRightsTileSerializer(ArchesTileSerializer):
class Meta:
model = TileModel
graph_slug = "scheme"
root_node = "rights"
fields = "__all__"


class SchemeLabelSerializer(ArchesModelSerializer):
class Meta:
model = ResourceInstance
Expand Down
9 changes: 5 additions & 4 deletions arches_lingo/src/arches_lingo/api.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import arches from "arches";
import Cookies from "js-cookie";
import type { AppellativeStatus, SchemeInstance } from "@/arches_lingo/types";
import type { AppellativeStatus, SchemeInstance, SchemeRights } from "@/arches_lingo/types";

function getToken() {
const token = Cookies.get("csrftoken");
Expand Down Expand Up @@ -225,15 +225,16 @@ export const updateSchemeNamespace = async (

export const updateSchemeRights = async (
schemeId: string,
schemeRights: SchemeInstance,
tileId: string,
schemeRightsValue: SchemeRights,
) => {
const response = await fetch(arches.urls.api_scheme_rights(schemeId), {
const response = await fetch(arches.urls.api_scheme_rights_tile(schemeId, tileId), {
method: "PATCH",
headers: {
"X-CSRFTOKEN": getToken(),
"Content-Type": "application/json",
},
body: JSON.stringify(schemeRights),
body: JSON.stringify(schemeRightsValue),
});
const parsed = await response.json();
if (!response.ok) throw new Error(parsed.message || response.statusText);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import SchemeNamespace from "@/arches_lingo/components/scheme/report/SchemeNames
import SchemeStandard from "@/arches_lingo/components/scheme/report/SchemeStandard.vue";
import SchemeLabel from "@/arches_lingo/components/scheme/report/SchemeLabel.vue";
import SchemeNote from "@/arches_lingo/components/scheme/report/SchemeNote.vue";
import SchemeLicense from "@/arches_lingo/components/scheme/report/SchemeLicense.vue";
import type { SectionTypes } from "@/arches_lingo/types.ts";
const { $gettext } = useGettext();
Expand Down Expand Up @@ -48,7 +49,7 @@ const schemeComponents = [
{
component: SchemeLicense,
id: "license",
editorTabName: $gettext("Scheme Rights"),
editorName: $gettext("Scheme Rights"),
},
];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,40 +1,52 @@
<script setup lang="ts">
import { inject, onMounted, ref, type Ref } from "vue";
import { inject, onMounted, ref, toRaw, type Ref } from "vue";
import { useRoute } from "vue-router";
import { useGettext } from "vue3-gettext";
import Button from "primevue/button";
import SchemeReportSection from "@/arches_lingo/components/scheme/report/SchemeSection.vue";
import {
fetchSchemeRights,
updateSchemeRights,
fetchPersonRdmSystemList,
fetchGroupRdmSystemList,
fetchControlledListOptions,
} from "@/arches_lingo/api.ts";
import type {
DataComponentMode,
ResourceInstanceReference,
ResourceInstanceResult,
SchemeInstance,
ControlledListItem,
ControlledListItemResult,
SchemeRights,
} from "@/arches_lingo/types";
import { selectedLanguageKey, VIEW, EDIT } from "@/arches_lingo/constants.ts";
import ResourceInstanceRelationships from "../../generic/ResourceInstanceRelationships.vue";
import ControlledListItem from "../../generic/ControlledListItem.vue";
import {
selectedLanguageKey,
VIEW,
EDIT,
RIGHT_TYPE_CONTROLLED_LIST,
} from "@/arches_lingo/constants.ts";
import ResourceInstanceRelationships from "@/arches_lingo/components/generic/ResourceInstanceRelationships.vue";
import ReferenceDatatype from "@/arches_lingo/components/generic/ReferenceDatatype.vue";
import type { Language } from "@/arches_vue_utils/types.ts";
onMounted(async () => {
getSectionValue();
});
defineEmits(["openEditor"]);
defineProps<{
mode?: DataComponentMode;
}>();
const schemeRights = ref<SchemeInstance>();
const emit = defineEmits(["openEditor", "update"]);
const schemeRight = ref<SchemeRights>();
const tileid = ref<string>();
const route = useRoute();
const actorRdmOptions = ref<ResourceInstanceReference[]>();
const selectedLanguage = inject(selectedLanguageKey) as Ref<Language>;
const rightTypeOptions = ref<ControlledListItem[]>();
async function getOptions(): Promise<ResourceInstanceReference[]> {
async function getActorOptions(): Promise<ResourceInstanceReference[]> {
const options_person = await fetchPersonRdmSystemList();
const options_group = await fetchGroupRdmSystemList();
const options = options_person.concat(options_group);
Expand All @@ -50,37 +62,55 @@ async function getOptions(): Promise<ResourceInstanceReference[]> {
});
return results;
};
function onSchemeRightsUpdate(val: string[]) {
const schemeRightsValue = schemeRights.value!;
if (actorRdmOptions.value) {
const options = actorRdmOptions.value?.filter((option) =>
async function getControlledListOptions(listId: string): Promise<ControlledListItem[]> {
const parsed = await fetchControlledListOptions(listId);
const options = parsed.items.map(
(item: ControlledListItemResult): ControlledListItem => ({
list_id: item.list_id,
uri: item.uri,
labels: item.values
}),
);
return options;
};
function onUpdateReferenceDatatype(
node: keyof SchemeRights,
val: ControlledListItem[],
) {
(schemeRight.value[node] as unknown) = val.map((item) => toRaw(item));
};
function onUpdateResourceInstance(
node: keyof SchemeRights,
val: string[],
options: ResourceInstanceReference[],
) {
if (val.length > 0) {
const selectedOptions = options.filter((option) =>
val.includes(option.resourceId),
);
if (!schemeRightsValue?.rights) {
schemeRightsValue.rights = {
right_holder: options,
right_type: [],
};
} else {
schemeRightsValue.rights.right_holder = options;
}
(schemeRight.value[node] as unknown) = selectedOptions;
}
};
async function save() {
await updateSchemeRights(
route.params.id as string,
schemeRights.value as SchemeInstance,
tileid.value as string,
schemeRight.value as SchemeRights,
);
emit("update");
};
async function getSectionValue() {
const options = !actorRdmOptions.value
? await getOptions()
: actorRdmOptions.value;
const actorOptions = await getActorOptions();
const scheme = await fetchSchemeRights(route.params.id as string);
const hydratedResults = options.map((option) => {
const savedSource = scheme.rights?.right_holder.find(
console.log(scheme);
schemeRight.value = scheme?.rights;
console.log(schemeRight.value);
tileid.value = schemeRight.value?.tileid;
actorRdmOptions.value = actorOptions.map((option) => {
const savedSource = schemeRight.value?.right_holder?.find(
(source: ResourceInstanceReference) =>
source.resourceId === option.resourceId,
);
Expand All @@ -90,11 +120,10 @@ async function getSectionValue() {
return option;
}
});
actorRdmOptions.value = hydratedResults;
schemeRights.value = scheme;
rightTypeOptions.value = await getControlledListOptions(RIGHT_TYPE_CONTROLLED_LIST);
};
defineExpose({ save, getSectionValue });
defineExpose({ getSectionValue });
const { $gettext } = useGettext();
</script>

Expand All @@ -103,33 +132,41 @@ const { $gettext } = useGettext();
<div v-if="!mode || mode === VIEW">
<SchemeReportSection
:title-text="$gettext('Scheme Rights')"
:button-text="$gettext('Update Scheme Rights')"
@open-editor="$emit('openEditor')"
>
<h4>{{ $gettext('Rights Holders') }}</h4>
<ResourceInstanceRelationships
:value="schemeRights?.rights?.right_holder"
:mode="VIEW"
:value="schemeRight?.right_holder"
:mode=VIEW
/>
<h4>{{ $gettext('Rights Type') }}</h4>
<!-- <ControlledListItem
:value="schemeRights?.rights?.right_type"
:mode="VIEW"
/> -->
<ReferenceDatatype
:value="schemeRight?.right_type"
:mode=VIEW
/>
</SchemeReportSection>
</div>
<div v-if="mode === EDIT">
<h4>{{ $gettext('Rights Holders') }}</h4>
<ResourceInstanceRelationships
:value="schemeRights?.rights?.right_holder"
:value="schemeRight?.right_holder"
:options="actorRdmOptions"
:mode="EDIT"
@update="onSchemeRightsUpdate"
@update="(val) => onUpdateResourceInstance('right_holder', val, actorRdmOptions ?? [])"
/>
<h4>{{ $gettext('Rights Type') }}</h4>
<!-- <ControlledListItem
:value="schemeRights?.rights?.right_type"
<ReferenceDatatype
:value="schemeRight?.right_type"
:options="rightTypeOptions"
:multi-value="false"
:mode="EDIT"
/> -->
@update="(val) => onUpdateReferenceDatatype('right_type', val)"
/>
<Button
:label="$gettext('Update')"
@click="save"
></Button>
</div>
</div>
</template>
1 change: 1 addition & 0 deletions arches_lingo/src/arches_lingo/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ export const STATUSES_CONTROLLED_LIST = "2cc0e054-ef9b-41ae-8e86-e0c3b4e7ca00";
export const METATYPES_CONTROLLED_LIST = "ef69e772-de53-45fe-98d4-bf3e7b10eb57";
export const EVENT_TYPES_CONTROLLED_LIST =
"6eaa2c6f-af83-464c-9200-051c4cfe7e8e";
export const RIGHT_TYPE_CONTROLLED_LIST = "1c950e16-3fcf-4f33-9e5e-ce5c6c992cca";
11 changes: 7 additions & 4 deletions arches_lingo/src/arches_lingo/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ export interface SchemeStatement {
statement_data_assignment_actor: ResourceInstanceReference[];
}

export interface SchemeRights {
tileid: string;
right_holder?: ResourceInstanceReference[];
right_type?: ControlledListItem[];
}

export interface SchemeInstance {
namespace?: {
namespace_name: string;
Expand All @@ -139,10 +145,7 @@ export interface SchemeInstance {
};
appellative_status?: AppellativeStatus[];
statement?: SchemeStatement[];
rights?: {
right_holder: ResourceInstanceReference[];
right_type: ControlledListItem[];
};
rights?: SchemeRights;
}

export interface SchemeResource {
Expand Down
2 changes: 2 additions & 0 deletions arches_lingo/templates/arches_urls.htm
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@
api_group_list="{% url 'api-group-list' %}"
api_person_list="{% url 'api-person-list' %}"
api_scheme_rights='(pluginid)=>{return "{% url "api-scheme-rights" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" %}".replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", pluginid)}'
api_scheme_rights='(resourceid)=>{return "{% url "api-scheme-rights" "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" %}".replace("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa", resourceid)}'
api_scheme_rights_tile='(resourceid, tileid)=>{return "{% url "api-scheme-rights-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)}'
></div>
{% endblock arches_urls %}
6 changes: 6 additions & 0 deletions arches_lingo/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
PersonRdmSystemSerializerView,
SchemeCreationView,
SchemeRightsView,
SchemeRightsTileView,
SchemeDetailView,
SchemeLabelTileView,
SchemeLabelView,
Expand Down Expand Up @@ -69,6 +70,11 @@
SchemeRightsView.as_view(),
name="api-scheme-rights",
),
path(
"api/scheme/<uuid:resource_id>/rights/<uuid:pk>",
SchemeRightsTileView.as_view(),
name="api-scheme-rights-tile",
),
path(
"api/scheme/<uuid:pk>/label",
SchemeLabelView.as_view(),
Expand Down
8 changes: 8 additions & 0 deletions arches_lingo/views/api/pythonic_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
SchemeNoteSerializer,
SchemeNoteTileSerializer,
SchemeSerializer,
SchemeRightsSerializer,
SchemeRightsTileSerializer,
SchemeStatementSerializer,
TextualWorkRdmSystemSerializer,
GroupRdmSystemSerializer,
Expand Down Expand Up @@ -67,6 +69,12 @@ class SchemeRightsView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView):
permission_classes = [RDMAdministrator]
serializer_class = SchemeRightsSerializer


class SchemeRightsTileView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView):
permission_classes = [RDMAdministrator]
serializer_class = SchemeRightsTileSerializer


class SchemeLabelView(ArchesModelAPIMixin, RetrieveUpdateDestroyAPIView):
permission_classes = [RDMAdministrator]
serializer_class = SchemeLabelSerializer
Expand Down

0 comments on commit 6259b4b

Please sign in to comment.