Skip to content

Commit

Permalink
Merge pull request #283 from performant-software/feature/basira275_au…
Browse files Browse the repository at this point in the history
…thorized_vocabulary

BASIRA #275 - Authorized vocabulary
  • Loading branch information
dleadbetter authored Dec 16, 2024
2 parents 0484a18 + c2e950a commit 8e9e7b1
Show file tree
Hide file tree
Showing 24 changed files with 250 additions and 151 deletions.
4 changes: 4 additions & 0 deletions app/controllers/api/places_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
class Api::PlacesController < Api::BaseController
# Search attributes
search_attributes :name, :city, :state, :country

# Preloads
preloads :qualifications, only: :show
end
15 changes: 3 additions & 12 deletions app/controllers/api/value_lists_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ class Api::ValueListsController < Api::BaseController
# Search columns
search_attributes :object, :group, :human_name, :comment

# Preloads
preloads :qualifications, only: [:index, :show]

def objects_list
objects_list = ValueList
.all
Expand All @@ -26,18 +29,6 @@ def groups_list
}
end

def authorized_vocabularies
vocabs_list = ValueList
.where.not(authorized_vocabulary: nil)
.order(:authorized_vocabulary)
.distinct
.pluck(:authorized_vocabulary)

render json: {
authorized_vocabularies: vocabs_list
}
end

protected

def apply_filters(query)
Expand Down
6 changes: 4 additions & 2 deletions app/models/place.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class Place < ApplicationRecord
# Includes
include Qualifiable
include Recordable
include Search::Place

Expand All @@ -11,6 +12,7 @@ class Place < ApplicationRecord

# Resourceable parameters
allow_params :name, :place_type, :lat, :long, :city, :state, :country, :url, :database_value, :notes, :same_as,
:part_of, locations_attributes: [:id, :locateable_id, :locateable_type, :description, :certainty,
:notes, :_destroy, qualifications_attributes: [:id, :value_list_id, :notes, :persistent, :_destroy]]
:part_of, :authorized_vocabulary_url,
locations_attributes: [:id, :locateable_id, :locateable_type, :description, :certainty, :notes, :_destroy,
qualifications_attributes: [:id, :value_list_id, :notes, :persistent, :_destroy]]
end
4 changes: 1 addition & 3 deletions app/models/value_list.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
class ValueList < ApplicationRecord
# Includes
include Qualifiable
include Recordable

# Relationships
has_many :qualifications

# Resource params
allow_params :authorized_vocabulary, :comment, :object, :group, :human_name, :authorized_vocabulary_url, :database_value

Expand Down
5 changes: 2 additions & 3 deletions app/serializers/people_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ class PeopleSerializer < BaseSerializer
include LocateableSerializer

index_attributes :id, :name, :display_name, :person_type, qualifications: QualificationsSerializer
show_attributes :id, :name, :display_name, :person_type, :authorized_vocabulary, :url, :database_value,
:comment, :part_of, :same_as, :artist_birth_date, :artist_death_date, :years_active,
qualifications: QualificationsSerializer
show_attributes :id, :name, :display_name, :person_type, :url, :database_value, :comment, :part_of, :same_as,
:artist_birth_date, :artist_death_date, :years_active, qualifications: QualificationsSerializer

# For unauthenticated users, only display participations for artworks that are published
show_attributes(:participations) do |person, current_user|
Expand Down
3 changes: 2 additions & 1 deletion app/serializers/places_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class PlacesSerializer < BaseSerializer
index_attributes :id, :name, :place_type, :lat, :long, :city, :state, :country
show_attributes :id, :name, :place_type, :lat, :long, :city, :state, :country, :url, :database_value, :notes, :same_as, :part_of
show_attributes :id, :name, :place_type, :lat, :long, :city, :state, :country, :url, :database_value, :notes,
:same_as, :part_of, :authorized_vocabulary_url, qualifications: QualificationsSerializer

# For unauthenticated users, only display locations for artworks that are published
show_attributes(:locations) do |place, current_user|
Expand Down
8 changes: 4 additions & 4 deletions app/serializers/value_lists_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class ValueListsSerializer < BaseSerializer
index_attributes :id, :object, :group, :human_name, :authorized_vocabulary, :authorized_vocabulary_url,
:database_value, :comment, :qualifications_count
index_attributes :id, :object, :group, :human_name, :authorized_vocabulary_url, :database_value, :comment,
:qualifications_count, qualifications: QualificationsSerializer

show_attributes :id, :object, :group, :human_name, :authorized_vocabulary, :authorized_vocabulary_url,
:database_value, :comment, :qualifications_count
show_attributes :id, :object, :group, :human_name, :authorized_vocabulary_url, :database_value, :comment,
:qualifications_count, qualifications: QualificationsSerializer
end
9 changes: 4 additions & 5 deletions client/src/components/PersonForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,11 @@ const PersonForm = (props: Props) => (
required={props.isRequired('years_active')}
value={props.item.years_active || ''}
/>
<Form.Input
error={props.isError('authorized_vocabulary')}
<ValueListDropdown
{...props}
group='Authorized Vocabulary'
label={props.t('Person.labels.authorizedVocabulary')}
onChange={props.onTextInputChange.bind(this, 'authorized_vocabulary')}
required={props.isRequired('authorized_vocabulary')}
value={props.item.authorized_vocabulary || ''}
object='General'
/>
<Form.Input
error={props.isError('url')}
Expand Down
14 changes: 14 additions & 0 deletions client/src/components/PlaceForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { GoogleScript } from '@performant-software/shared-components';
import { Form, Grid } from 'semantic-ui-react';
import _ from 'underscore';
import Countries from '../resources/Countries.json';
import ValueListDropdown from './ValueListDropdown';

import type { EditContainerProps } from 'react-components/types';
import type { Translateable } from '../types/Translateable';
Expand Down Expand Up @@ -110,6 +111,19 @@ const PlaceForm = (props: Props) => {
onChange={props.onTextInputChange.bind(this, 'url')}
value={props.item.url || ''}
/>
<ValueListDropdown
{...props}
group='Authorized Vocabulary'
label={props.t('Place.labels.authorizedVocabulary')}
object='General'
/>
<Form.Input
error={props.isError('authorized_vocabulary_url')}
label={props.t('Place.labels.authorizedVocabularyUrl')}
required={props.isRequired('authorized_vocabulary_url')}
onChange={props.onTextInputChange.bind(this, 'authorized_vocabulary_url')}
value={props.item.authorized_vocabulary_url || ''}
/>
<Form.Input
error={props.isError('database_value')}
label={props.t('Place.labels.databaseValue')}
Expand Down
162 changes: 70 additions & 92 deletions client/src/components/ValueListModal.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// @flow

import React, { useEffect, useState } from 'react';
import React from 'react';
import { withTranslation } from 'react-i18next';
import { Dropdown, Form, Modal } from 'semantic-ui-react';
import ValueLists from '../services/ValueLists';
import { Form, Modal } from 'semantic-ui-react';
import ValueListDropdown from './ValueListDropdown';

import type { EditContainerProps } from 'react-components/types';
import type { Translateable } from '../types/Translateable';
Expand All @@ -13,95 +13,73 @@ type Props = EditContainerProps & Translateable & {
item: ValueList
};

const ValueListModal = (props: Props) => {
const [authorizedVocabulariesList, setAuthorizedVocabulariesList] = useState([]);

useEffect(() => {
ValueLists.getAuthorizedVocabulariesList().then(({ data }) => {
setAuthorizedVocabulariesList(data.authorized_vocabularies.map((vocab) => ({
key: vocab,
value: vocab,
text: vocab
})));
});
}, []);

return (
<Modal
as={Form}
className='value-list-modal'
centered={false}
noValidate
open
>
<Modal.Header
content={props.item.id
? props.t('ValueList.title.edit')
: props.t('ValueList.title.add')}
const ValueListModal = (props: Props) => (
<Modal
as={Form}
className='value-list-modal'
centered={false}
noValidate
open
>
<Modal.Header
content={props.item.id
? props.t('ValueList.title.edit')
: props.t('ValueList.title.add')}
/>
<Modal.Content>
<Form.Input
disabled={props.item.qualifications_count > 0}
error={props.isError('object')}
label={props.t('ValueList.labels.objectName')}
onChange={props.onTextInputChange.bind(this, 'object')}
required={props.isRequired('object')}
value={props.item.object || ''}
/>
<Modal.Content>
<Form.Input
disabled={props.item.qualifications_count > 0}
error={props.isError('object')}
label={props.t('ValueList.labels.objectName')}
onChange={props.onTextInputChange.bind(this, 'object')}
required={props.isRequired('object')}
value={props.item.object || ''}
/>
<Form.Input
disabled={props.item.qualifications_count > 0}
error={props.isError('group')}
label={props.t('ValueList.labels.groupName')}
onChange={props.onTextInputChange.bind(this, 'group')}
required={props.isRequired('group')}
value={props.item.group || ''}
/>
<Form.Input
error={props.isError('human_name')}
label={props.t('ValueList.labels.humanName')}
onChange={props.onTextInputChange.bind(this, 'human_name')}
required={props.isRequired('human_name')}
value={props.item.human_name || ''}
/>
<Form.Input
error={props.isError('authorized_vocabulary')}
label={props.t('ValueList.labels.authorizedVocabulary')}
required={props.isRequired('authorized_vocabulary')}
>
<Dropdown
fluid
onChange={props.onTextInputChange.bind(this, 'authorized_vocabulary')}
options={authorizedVocabulariesList}
searchable
selection
value={props.item.authorized_vocabulary || ''}
/>
</Form.Input>
<Form.Input
error={props.isError('authorized_vocabulary_url')}
label={props.t('ValueList.labels.authorizedVocabularyUrl')}
onChange={props.onTextInputChange.bind(this, 'authorized_vocabulary_url')}
required={props.isRequired('authorized_vocabulary_url')}
value={props.item.authorized_vocabulary_url || ''}
/>
<Form.Input
error={props.isError('database_value')}
label={props.t('ValueList.labels.databaseValue')}
onChange={props.onTextInputChange.bind(this, 'database_value')}
required={props.isRequired('database_value')}
value={props.item.database_value || ''}
/>
<Form.TextArea
error={props.isError('comment')}
label={props.t('ValueList.labels.comment')}
onChange={props.onTextInputChange.bind(this, 'comment')}
required={props.isRequired('comment')}
value={props.item.comment || ''}
/>
</Modal.Content>
{ props.children }
</Modal>
);
};
<Form.Input
disabled={props.item.qualifications_count > 0}
error={props.isError('group')}
label={props.t('ValueList.labels.groupName')}
onChange={props.onTextInputChange.bind(this, 'group')}
required={props.isRequired('group')}
value={props.item.group || ''}
/>
<Form.Input
error={props.isError('human_name')}
label={props.t('ValueList.labels.humanName')}
onChange={props.onTextInputChange.bind(this, 'human_name')}
required={props.isRequired('human_name')}
value={props.item.human_name || ''}
/>
<ValueListDropdown
{...props}
group='Authorized Vocabulary'
label={props.t('ValueList.labels.authorizedVocabulary')}
object='General'
/>
<Form.Input
error={props.isError('authorized_vocabulary_url')}
label={props.t('ValueList.labels.authorizedVocabularyUrl')}
onChange={props.onTextInputChange.bind(this, 'authorized_vocabulary_url')}
required={props.isRequired('authorized_vocabulary_url')}
value={props.item.authorized_vocabulary_url || ''}
/>
<Form.Input
error={props.isError('database_value')}
label={props.t('ValueList.labels.databaseValue')}
onChange={props.onTextInputChange.bind(this, 'database_value')}
required={props.isRequired('database_value')}
value={props.item.database_value || ''}
/>
<Form.TextArea
error={props.isError('comment')}
label={props.t('ValueList.labels.comment')}
onChange={props.onTextInputChange.bind(this, 'comment')}
required={props.isRequired('comment')}
value={props.item.comment || ''}
/>
</Modal.Content>
{ props.children }
</Modal>
);

export default withTranslation()(ValueListModal);
4 changes: 3 additions & 1 deletion client/src/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,9 @@
"notes": "Notes",
"state": "State",
"type": "Type",
"url": "Authorized Vocabulary URL"
"url": "Institutional URL",
"authorizedVocabulary": "Authorized vocabulary",
"authorizedVocabularyUrl": "Authorized vocabulary URL"
},
"locations": {
"columns": {
Expand Down
4 changes: 4 additions & 0 deletions client/src/pages/admin/ValueLists.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.value-lists > .tab > .ui.menu {
overflow: auto;
padding-bottom: 0.25em;
}
Loading

0 comments on commit 8e9e7b1

Please sign in to comment.