Skip to content

Commit

Permalink
BASIRA #275 - Converting value_lists.authorized_vocabulary and people…
Browse files Browse the repository at this point in the history
….authorized_vocabulary fields to value lists
  • Loading branch information
dleadbetter committed Dec 11, 2024
1 parent 0484a18 commit fa9379c
Show file tree
Hide file tree
Showing 14 changed files with 166 additions and 127 deletions.
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
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
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
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);
11 changes: 8 additions & 3 deletions client/src/transforms/ValueList.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import _ from 'underscore';
import BaseTransform from './BaseTransform';
import Qualifications from './Qualifications';

import type { ValueList as ValueListType } from '../types/ValueList';

Expand Down Expand Up @@ -52,12 +53,16 @@ class ValueList extends BaseTransform {
/**
* Returns the value_list object to be sent to the server on POST/PUT requests.
*
* @param option
* @param valueList
*
* @returns {*}
*/
toPayload(option: ValueListType) {
return { value_list: _.pick(option, this.PAYLOAD_KEYS) };
toPayload(valueList: ValueListType) {
return {
value_list: {
..._.pick(valueList, this.PAYLOAD_KEYS),
...Qualifications.toPayload(valueList)
}};
}
}

Expand Down
1 change: 0 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
resources :visual_contexts, except: :index
resources :users

get 'authorized_vocabularies' => 'value_lists#authorized_vocabularies'
get 'value_lists_objects', to: 'value_lists#objects_list'
get 'value_lists_groups', to: 'value_lists#groups_list'

Expand Down
41 changes: 41 additions & 0 deletions db/data/20241211163139_create_authorized_vocabulary_value_lists.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

class CreateAuthorizedVocabularyValueLists < ActiveRecord::Migration[7.0]
def up
execute <<-SQL.squish
INSERT INTO value_lists (object, "group", human_name, created_at, updated_at)
SELECT DISTINCT 'General', 'Authorized Vocabulary', authorized_vocabulary, current_timestamp, current_timestamp
FROM value_lists
WHERE authorized_vocabulary IS NOT NULL
UNION
SELECT DISTINCT 'General', 'Authorized Vocabulary', authorized_vocabulary, current_timestamp, current_timestamp
FROM people
WHERE authorized_vocabulary IS NOT NULL
ORDER BY authorized_vocabulary
SQL

execute <<-SQL.squish
INSERT INTO qualifications (qualifiable_id, qualifiable_type, value_list_id)
SELECT value_lists.id, 'ValueList', v.id
FROM value_lists
JOIN value_lists v ON v.human_name = value_lists.authorized_vocabulary
AND v.object = 'General'
AND v.group = 'Authorized Vocabulary'
WHERE value_lists.authorized_vocabulary IS NOT NULL
SQL

execute <<-SQL.squish
INSERT INTO qualifications (qualifiable_id, qualifiable_type, value_list_id)
SELECT people.id, 'Person', value_lists.id
FROM people
JOIN value_lists ON value_lists.human_name = people.authorized_vocabulary
AND value_lists.object = 'General'
AND value_lists.group = 'Authorized Vocabulary'
WHERE people.authorized_vocabulary IS NOT NULL
SQL
end

def down
raise ActiveRecord::IrreversibleMigration
end
end
21 changes: 21 additions & 0 deletions db/data/20241211173335_reset_value_list_qualifications_count.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

class ResetValueListQualificationsCount < ActiveRecord::Migration[7.0]
def up
execute <<-SQL.squish
WITH qualification_counts AS (
SELECT qualifications.value_list_id, COUNT(*) AS qualifications_count
FROM qualifications
GROUP BY qualifications.value_list_id
)
UPDATE value_lists
SET qualifications_count = qualification_counts.qualifications_count
FROM qualification_counts
WHERE qualification_counts.value_list_id = value_lists.id
SQL
end

def down
raise ActiveRecord::IrreversibleMigration
end
end
2 changes: 1 addition & 1 deletion db/data_schema.rb
Original file line number Diff line number Diff line change
@@ -1 +1 @@
DataMigrate::Data.define(version: 20241127155125)
DataMigrate::Data.define(version: 20241211173335)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class RemoveValueListsAuthorizedVocabulary < ActiveRecord::Migration[7.0]
def change
remove_column :value_lists, :authorized_vocabulary
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class RemovePeopleAuthorizedVocabulary < ActiveRecord::Migration[7.0]
def change
remove_column :people, :authorized_vocabulary
end
end
4 changes: 1 addition & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_12_03_181033) do
ActiveRecord::Schema[7.0].define(version: 2024_12_11_201922) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_stat_statements"
enable_extension "plpgsql"
Expand Down Expand Up @@ -180,7 +180,6 @@
t.string "name"
t.string "display_name"
t.string "person_type"
t.string "authorized_vocabulary"
t.string "url"
t.string "database_value"
t.string "comment"
Expand Down Expand Up @@ -288,7 +287,6 @@
t.string "human_name"
t.string "authorized_vocabulary_url"
t.text "comment"
t.string "authorized_vocabulary"
t.string "airtable_id"
t.datetime "airtable_timestamp", precision: nil
t.datetime "created_at", null: false
Expand Down

0 comments on commit fa9379c

Please sign in to comment.