From 8a06af6872693ac04d59e5823affa4db9a69be54 Mon Sep 17 00:00:00 2001 From: Luka van der Plas Date: Fri, 27 Sep 2024 13:35:49 +0200 Subject: [PATCH] simplify icon decision for locations and agents --- backend/person/models.py | 3 +++ backend/person/types/AgentDescriptionType.py | 7 ++++++- frontend/generated/graphql.ts | 11 +++++------ frontend/generated/schema.graphql | 1 + .../agent-form/agent-form.component.html | 2 +- .../data-entry/agent-form/agent-form.component.ts | 2 ++ .../src/app/data-entry/agent-form/agent.graphql | 1 + .../location-form/location-form.component.html | 2 +- .../location-form/location-form.component.ts | 2 ++ .../episode-preview/episode-preview.component.html | 3 +-- .../episode-preview/episode-preview.component.ts | 13 +++---------- frontend/src/app/data-entry/source/source.graphql | 5 +---- frontend/src/app/shared/icons-utils.ts | 14 ++++++++++++++ frontend/src/app/shared/icons.ts | 4 ++-- 14 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 frontend/src/app/shared/icons-utils.ts diff --git a/backend/person/models.py b/backend/person/models.py index 529fe4cd..30fb525a 100644 --- a/backend/person/models.py +++ b/backend/person/models.py @@ -99,6 +99,9 @@ def clean(self): "Only groups can describe multiple historical figures" ) + def identified(self): + return self.describes.filter(identifiable=True).exists() + class Gender(models.TextChoices): FEMALE = "FEMALE", "Female" diff --git a/backend/person/types/AgentDescriptionType.py b/backend/person/types/AgentDescriptionType.py index 9f7e2650..02e5f453 100644 --- a/backend/person/types/AgentDescriptionType.py +++ b/backend/person/types/AgentDescriptionType.py @@ -1,4 +1,4 @@ -from graphene import Field, List, ResolveInfo, NonNull +from graphene import Field, List, ResolveInfo, NonNull, Boolean from graphene_django import DjangoObjectType from django.db.models import QuerySet @@ -18,6 +18,7 @@ class AgentDescriptionType(EntityDescriptionType, DjangoObjectType): gender = Field(AgentDescriptionGenderType) location = Field(AgentDescriptionLocationType) episodes = List(NonNull(EpisodeAgentType), required=True) + identified = Boolean(required=True) class Meta: model = AgentDescription @@ -55,3 +56,7 @@ def resolve_episodes( parent: AgentDescription, info: ResolveInfo ) -> QuerySet[EpisodeAgent]: return EpisodeAgent.objects.filter(agent=parent) + + @staticmethod + def resolve_identified(parent: AgentDescription, info: ResolveInfo) -> bool: + return parent.identified() diff --git a/frontend/generated/graphql.ts b/frontend/generated/graphql.ts index c5993a6d..e485d4ad 100644 --- a/frontend/generated/graphql.ts +++ b/frontend/generated/graphql.ts @@ -54,6 +54,7 @@ export type AgentDescriptionType = EntityDescription & { episodes: Array; gender?: Maybe; id: Scalars['ID']['output']; + identified: Scalars['Boolean']['output']; /** Whether this agent is a group of people (e.g. 'the nuns of Poitiers'). */ isGroup: Scalars['Boolean']['output']; location?: Maybe; @@ -1062,7 +1063,7 @@ export type DataEntryAgentQueryVariables = Exact<{ }>; -export type DataEntryAgentQuery = { __typename?: 'Query', agentDescription?: { __typename?: 'AgentDescriptionType', id: string, name: string, description: string, isGroup: boolean, source: { __typename?: 'SourceType', id: string, name: string } } | null }; +export type DataEntryAgentQuery = { __typename?: 'Query', agentDescription?: { __typename?: 'AgentDescriptionType', id: string, name: string, description: string, isGroup: boolean, identified: boolean, source: { __typename?: 'SourceType', id: string, name: string } } | null }; export type DataEntryUpdateAgentMutationVariables = Exact<{ input: UpdateAgentInput; @@ -1247,7 +1248,7 @@ export type DataEntrySourceDetailQueryVariables = Exact<{ }>; -export type DataEntrySourceDetailQuery = { __typename?: 'Query', source: { __typename?: 'SourceType', id: string, name: string, episodes: Array<{ __typename?: 'EpisodeType', id: string, name: string, description: string, summary: string, book: string, chapter: string, page: string, contributors: Array<{ __typename?: 'UserType', id: string, fullName: string }>, agents: Array<{ __typename?: 'AgentDescriptionType', id: string, name: string, isGroup: boolean, describes: Array<{ __typename?: 'HistoricalPersonType', id: string, identifiable: boolean }> }>, gifts: Array<{ __typename?: 'GiftDescriptionType', id: string, name: string }>, letters: Array<{ __typename?: 'LetterDescriptionType', id: string, name: string }>, spaces: Array<{ __typename?: 'SpaceDescriptionType', id: string, name: string, hasIdentifiableFeatures: boolean }> }> } }; +export type DataEntrySourceDetailQuery = { __typename?: 'Query', source: { __typename?: 'SourceType', id: string, name: string, episodes: Array<{ __typename?: 'EpisodeType', id: string, name: string, description: string, summary: string, book: string, chapter: string, page: string, contributors: Array<{ __typename?: 'UserType', id: string, fullName: string }>, agents: Array<{ __typename?: 'AgentDescriptionType', id: string, name: string, isGroup: boolean, identified: boolean }>, gifts: Array<{ __typename?: 'GiftDescriptionType', id: string, name: string }>, letters: Array<{ __typename?: 'LetterDescriptionType', id: string, name: string }>, spaces: Array<{ __typename?: 'SpaceDescriptionType', id: string, name: string, hasIdentifiableFeatures: boolean }> }> } }; export type DataEntrySourceListQueryVariables = Exact<{ [key: string]: never; }>; @@ -1443,6 +1444,7 @@ export const DataEntryAgentDocument = gql` name description isGroup + identified source { id name @@ -2101,10 +2103,7 @@ export const DataEntrySourceDetailDocument = gql` id name isGroup - describes { - id - identifiable - } + identified } gifts { id diff --git a/frontend/generated/schema.graphql b/frontend/generated/schema.graphql index af0629d3..86a2bbd6 100644 --- a/frontend/generated/schema.graphql +++ b/frontend/generated/schema.graphql @@ -39,6 +39,7 @@ type AgentDescriptionType implements EntityDescription { episodes: [EpisodeAgentType!]! gender: AgentDescriptionGenderType id: ID! + identified: Boolean! """Whether this agent is a group of people (e.g. 'the nuns of Poitiers').""" isGroup: Boolean! diff --git a/frontend/src/app/data-entry/agent-form/agent-form.component.html b/frontend/src/app/data-entry/agent-form/agent-form.component.html index 37537d03..561e8176 100644 --- a/frontend/src/app/data-entry/agent-form/agent-form.component.html +++ b/frontend/src/app/data-entry/agent-form/agent-form.component.html @@ -3,7 +3,7 @@

- + {{agentDescription.name}} ({{agentDescription.source.name}}) diff --git a/frontend/src/app/data-entry/agent-form/agent-form.component.ts b/frontend/src/app/data-entry/agent-form/agent-form.component.ts index a7bf3d1d..c69fed4d 100644 --- a/frontend/src/app/data-entry/agent-form/agent-form.component.ts +++ b/frontend/src/app/data-entry/agent-form/agent-form.component.ts @@ -4,6 +4,7 @@ import { dataIcons } from '@shared/icons'; import { DataEntryAgentGQL, DataEntryAgentQuery } from 'generated/graphql'; import { map, Observable, switchMap } from 'rxjs'; import { FormService } from '../shared/form.service'; +import { agentIcon } from '@shared/icons-utils'; @Component({ selector: 'lc-agent-form', @@ -16,6 +17,7 @@ export class AgentFormComponent { data$: Observable; dataIcons = dataIcons; + agentIcon = agentIcon; status$ = this.formService.status$; diff --git a/frontend/src/app/data-entry/agent-form/agent.graphql b/frontend/src/app/data-entry/agent-form/agent.graphql index b3d56359..f10d7f66 100644 --- a/frontend/src/app/data-entry/agent-form/agent.graphql +++ b/frontend/src/app/data-entry/agent-form/agent.graphql @@ -4,6 +4,7 @@ query DataEntryAgent($id: ID!) { name description isGroup + identified source { id name diff --git a/frontend/src/app/data-entry/location-form/location-form.component.html b/frontend/src/app/data-entry/location-form/location-form.component.html index 053a85b7..a63b8c87 100644 --- a/frontend/src/app/data-entry/location-form/location-form.component.html +++ b/frontend/src/app/data-entry/location-form/location-form.component.html @@ -3,7 +3,7 @@

- + {{spaceDescription.name}} ({{spaceDescription.source.name}}) diff --git a/frontend/src/app/data-entry/location-form/location-form.component.ts b/frontend/src/app/data-entry/location-form/location-form.component.ts index 07f623a9..8d4985ea 100644 --- a/frontend/src/app/data-entry/location-form/location-form.component.ts +++ b/frontend/src/app/data-entry/location-form/location-form.component.ts @@ -2,6 +2,7 @@ import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { Breadcrumb } from '@shared/breadcrumb/breadcrumb.component'; import { dataIcons } from '@shared/icons'; +import { locationIcon } from '@shared/icons-utils'; import { DataEntrySpaceDescriptionGQL, DataEntrySpaceDescriptionQuery } from 'generated/graphql'; import { map, Observable, switchMap } from 'rxjs'; @@ -15,6 +16,7 @@ export class LocationFormComponent { data$: Observable; dataIcons = dataIcons; + locationIcon = locationIcon; constructor( private route: ActivatedRoute, private spaceQuery: DataEntrySpaceDescriptionGQL diff --git a/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.html b/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.html index 0075d21a..2e3eead7 100644 --- a/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.html +++ b/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.html @@ -58,8 +58,7 @@ [routerLink]="['/data-entry', 'locations', space.id]" class="icon-link" > - + {{ space.name }} diff --git a/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.ts b/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.ts index 3ced9df0..faf22d19 100644 --- a/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.ts +++ b/frontend/src/app/data-entry/source/episode-preview/episode-preview.component.ts @@ -3,6 +3,7 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { ModalService } from "@services/modal.service"; import { ToastService } from "@services/toast.service"; import { dataIcons } from "@shared/icons"; +import { agentIcon, locationIcon } from "@shared/icons-utils"; import { DataEntryDeleteEpisodeGQL, DataEntrySourceDetailQuery, @@ -21,6 +22,8 @@ export class EpisodePreviewComponent { @Input({ required: true }) public episode!: QueriedEpisode; public dataIcons = dataIcons; + agentIcon = agentIcon; + locationIcon = locationIcon; constructor( private destroyRef: DestroyRef, @@ -42,16 +45,6 @@ export class EpisodePreviewComponent { }); } - public agentIcon(agent: QueriedEpisode["agents"][0]): string { - if (agent.isGroup) { - return dataIcons.group; - } - if (agent.describes?.some((person) => person?.identifiable)) { - return dataIcons.person; - } - return dataIcons.personUnknown; - } - private performDelete(episodeId: string): void { this.deleteEpisode .mutate( diff --git a/frontend/src/app/data-entry/source/source.graphql b/frontend/src/app/data-entry/source/source.graphql index 27f5405a..cffa8ce5 100644 --- a/frontend/src/app/data-entry/source/source.graphql +++ b/frontend/src/app/data-entry/source/source.graphql @@ -18,10 +18,7 @@ query DataEntrySourceDetail($id: ID!) { id name isGroup - describes { - id - identifiable - } + identified } gifts { id diff --git a/frontend/src/app/shared/icons-utils.ts b/frontend/src/app/shared/icons-utils.ts new file mode 100644 index 00000000..8219538f --- /dev/null +++ b/frontend/src/app/shared/icons-utils.ts @@ -0,0 +1,14 @@ +import { dataIcons } from "./icons"; + +export const agentIcon = (agent: { isGroup: boolean, identified: boolean }): string => { + if (agent.isGroup) { + return dataIcons.group; + } + if (agent.identified) { + return dataIcons.personIdentified; + } + return dataIcons.person; +} + +export const locationIcon = (location: { hasIdentifiableFeatures: boolean }): string => + location.hasIdentifiableFeatures ? dataIcons.locationIdentified : dataIcons.location; diff --git a/frontend/src/app/shared/icons.ts b/frontend/src/app/shared/icons.ts index 0d1360c9..0ada0cb4 100644 --- a/frontend/src/app/shared/icons.ts +++ b/frontend/src/app/shared/icons.ts @@ -27,8 +27,8 @@ export const authIcons = { export const dataIcons = { source: 'book', episode: 'bookmark', - person: 'person-fill', - personUnknown: 'person', + person: 'person', + personIdentified: 'person-fill', group: 'people', location: 'geo-alt', locationIdentified: 'geo-alt-fill',