diff --git a/web-app/django/VIM/apps/instruments/management/commands/import_instruments.py b/web-app/django/VIM/apps/instruments/management/commands/import_instruments.py index bc477b1..a0a32d6 100644 --- a/web-app/django/VIM/apps/instruments/management/commands/import_instruments.py +++ b/web-app/django/VIM/apps/instruments/management/commands/import_instruments.py @@ -86,7 +86,7 @@ def get_instrument_data(self, instrument_ids: list[str]) -> list[dict]: def create_database_objects(self, instrument_attrs: dict, ins_img_url: str) -> None: """ - Given a dictionary of instrument attributes and a url to an instrument image, + Given a dictionary of instrument attributes and a url to an instrument image, create the corresponding database objects. instrument_attrs [dict]: Dictionary of instrument attributes. See diff --git a/web-app/django/VIM/apps/instruments/management/commands/import_languages.py b/web-app/django/VIM/apps/instruments/management/commands/import_languages.py index f22ee35..da9d52d 100644 --- a/web-app/django/VIM/apps/instruments/management/commands/import_languages.py +++ b/web-app/django/VIM/apps/instruments/management/commands/import_languages.py @@ -6,10 +6,10 @@ class Command(BaseCommand): """ The import_languages command populates the database with languages in which instrument names can be provided in VIM. - + NOTE: For now, this script only imports English and French. """ - + help = "Imports possible languages for instrument names from Wikidata." def handle(self, *args, **options): diff --git a/web-app/django/VIM/apps/instruments/migrations/0001_initial.py b/web-app/django/VIM/apps/instruments/migrations/0001_initial.py index d2932b5..54f5491 100644 --- a/web-app/django/VIM/apps/instruments/migrations/0001_initial.py +++ b/web-app/django/VIM/apps/instruments/migrations/0001_initial.py @@ -5,64 +5,188 @@ class Migration(migrations.Migration): - initial = True - dependencies = [ - ] + dependencies = [] operations = [ migrations.CreateModel( - name='AVResource', + name="AVResource", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('type', models.CharField(choices=[('audio', 'Audio'), ('video', 'Video'), ('image', 'Image')], help_text='What type of audiovisual resource is this?', max_length=5)), - ('format', models.CharField()), - ('url', models.URLField(max_length=1000)), - ('instrument_date', models.DateField(blank=True, help_text='When was this instrument made?', null=True)), - ('instrument_maker', models.CharField(blank=True, help_text='Who made this instrument?')), - ('instrument_description', models.TextField(blank=True, help_text='Additional information about the instrument.')), - ('source_name', models.CharField(help_text='What is the name of the source of this AVResource?')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "type", + models.CharField( + choices=[ + ("audio", "Audio"), + ("video", "Video"), + ("image", "Image"), + ], + help_text="What type of audiovisual resource is this?", + max_length=5, + ), + ), + ("format", models.CharField()), + ("url", models.URLField(max_length=1000)), + ( + "instrument_date", + models.DateField( + blank=True, + help_text="When was this instrument made?", + null=True, + ), + ), + ( + "instrument_maker", + models.CharField(blank=True, help_text="Who made this instrument?"), + ), + ( + "instrument_description", + models.TextField( + blank=True, + help_text="Additional information about the instrument.", + ), + ), + ( + "source_name", + models.CharField( + help_text="What is the name of the source of this AVResource?" + ), + ), ], ), migrations.CreateModel( - name='Instrument', + name="Instrument", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('wikidata_id', models.CharField(max_length=20, unique=True)), - ('hornbostel_sachs_class', models.CharField(blank=True, help_text='Hornbostel-Sachs classification', max_length=50)), - ('mimo_class', models.CharField(blank=True, help_text='Musical Instrument Museums Online classification', max_length=50)), - ('default_image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='default_image_of', to='instruments.avresource')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("wikidata_id", models.CharField(max_length=20, unique=True)), + ( + "hornbostel_sachs_class", + models.CharField( + blank=True, + help_text="Hornbostel-Sachs classification", + max_length=50, + ), + ), + ( + "mimo_class", + models.CharField( + blank=True, + help_text="Musical Instrument Museums Online classification", + max_length=50, + ), + ), + ( + "default_image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name="default_image_of", + to="instruments.avresource", + ), + ), ], ), migrations.CreateModel( - name='Language', + name="Language", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('wikidata_code', models.CharField(help_text='Language code in Wikidata', unique=True)), - ('wikidata_id', models.CharField(help_text='Language ID (Q number) in Wikidata', unique=True)), - ('en_label', models.CharField(help_text='Language label in English')), - ('autonym', models.CharField(help_text='Language label in the language itself')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "wikidata_code", + models.CharField( + help_text="Language code in Wikidata", unique=True + ), + ), + ( + "wikidata_id", + models.CharField( + help_text="Language ID (Q number) in Wikidata", unique=True + ), + ), + ("en_label", models.CharField(help_text="Language label in English")), + ( + "autonym", + models.CharField(help_text="Language label in the language itself"), + ), ], ), migrations.CreateModel( - name='InstrumentName', + name="InstrumentName", fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=50)), - ('source_name', models.CharField(help_text='Who or what called the instrument this?', max_length=50)), - ('instrument', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='instruments.instrument')), - ('language', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='instruments.language')), + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=50)), + ( + "source_name", + models.CharField( + help_text="Who or what called the instrument this?", + max_length=50, + ), + ), + ( + "instrument", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="instruments.instrument", + ), + ), + ( + "language", + models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="instruments.language", + ), + ), ], ), migrations.AddField( - model_name='avresource', - name='instrument', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='instruments.instrument'), + model_name="avresource", + name="instrument", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="instruments.instrument" + ), ), migrations.AddField( - model_name='avresource', - name='instrument_description_language', - field=models.ForeignKey(blank=True, help_text='What language is Instrument Description written in?', null=True, on_delete=django.db.models.deletion.PROTECT, to='instruments.language'), + model_name="avresource", + name="instrument_description_language", + field=models.ForeignKey( + blank=True, + help_text="What language is Instrument Description written in?", + null=True, + on_delete=django.db.models.deletion.PROTECT, + to="instruments.language", + ), ), ] diff --git a/web-app/django/VIM/apps/instruments/models/instrument.py b/web-app/django/VIM/apps/instruments/models/instrument.py index 26d42e5..f7a6d3b 100644 --- a/web-app/django/VIM/apps/instruments/models/instrument.py +++ b/web-app/django/VIM/apps/instruments/models/instrument.py @@ -10,5 +10,11 @@ class Instrument(models.Model): null=True, related_name="default_image_of", ) - hornbostel_sachs_class = models.CharField(max_length=50, blank=True, help_text = "Hornbostel-Sachs classification") - mimo_class = models.CharField(max_length=50, blank=True, help_text = "Musical Instrument Museums Online classification") + hornbostel_sachs_class = models.CharField( + max_length=50, blank=True, help_text="Hornbostel-Sachs classification" + ) + mimo_class = models.CharField( + max_length=50, + blank=True, + help_text="Musical Instrument Museums Online classification", + ) diff --git a/web-app/django/VIM/apps/instruments/static/instruments/css/index.css b/web-app/django/VIM/apps/instruments/static/instruments/css/index.css new file mode 100644 index 0000000..e25b5ce --- /dev/null +++ b/web-app/django/VIM/apps/instruments/static/instruments/css/index.css @@ -0,0 +1,120 @@ + +@import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css"); + +h4 { + color: #435334; + font-size: 20px; + font-weight: 700; +} + +h5 { + color: #435334; +} + +hr { + border: 1.5px solid #435334; + margin-top: 0; +} + +/* sidebar */ +.sidebar-container { + background-color: white; + border: 3px solid #9EB384; + border-radius: 30px; + height: auto !important; +} + +.info-block { + background-color: #FAF1E4; + border: 1.5px solid #CEDEBD; + border-radius: 10px; + height: auto !important; +} + +.list-group-item { + border: none !important; + background-color: transparent !important; + color: #9EB384; +} + +.toggle-more{ + color: #435334; +} + +.toggle-more:hover { + cursor: pointer; + color: #9EB384; +} + +/* body */ +.body-container { + background-color: white; + border: 3px solid #9EB384; + border-radius: 30px; +} + +.display-btn { + font-weight: bold; + color: #435334; + font-size: 20px; +} + +.display-btn:focus { + border-color:#435334; +} + +.card { + background-color: #FAF1E4; +} + +.card-title { + color: #435334; +} + +.pagination-container { + color: #435334; +} + +.page-link { + color: #435334; +} + +.page-number, +.page-link:hover { + color: #9EB384; +} + +/* list view */ +.list-item-container { + min-height: 200px; + max-height: 300px; + overflow: hidden; +} + +.card-title h5:hover { + color: #9EB384; +} + +.more-info { + color: #435334; +} + +.more-info:hover { + border: 1px solid #435334; +} + +/* standard view */ +.square-box { + position: relative; + padding-top: 100%; + overflow: hidden; +} + +.square-box img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; +} \ No newline at end of file diff --git a/web-app/django/VIM/apps/instruments/static/instruments/js/DisplayMode.js b/web-app/django/VIM/apps/instruments/static/instruments/js/DisplayMode.js new file mode 100644 index 0000000..6b5566b --- /dev/null +++ b/web-app/django/VIM/apps/instruments/static/instruments/js/DisplayMode.js @@ -0,0 +1,87 @@ + +const masonryBtn = document.getElementById("masonry-btn"); +const listBtn = document.getElementById("list-btn"); +const stdBtn = document.getElementById("std-btn"); + +const masonryView = document.getElementById('masonry-view'); +const listView = document.getElementById('list-view'); +const stdView = document.getElementById('std-view'); + +updateDisplayMode(); + +function setDisplayMode(displayMode) { + localStorage.setItem('displayMode', displayMode); +} + +function getDisplayMode() { + return localStorage.getItem('displayMode'); +} + +function updateDisplayMode() { + const currentDisplayMode = getDisplayMode() || 'masonry'; + switch (currentDisplayMode) { + case 'masonry': + setMasonryView(); + masonryBtn.style.display = ""; + listBtn.style.display = "none"; + stdBtn.style.display = "none"; + masonryView.style.display = ""; + listView.style.display = "none"; + stdView.style.display = "none"; + break; + case 'list': + masonryBtn.style.display = "none"; + listBtn.style.display = ""; + stdBtn.style.display = "none"; + masonryView.style.display = "none"; + listView.style.display = ""; + stdView.style.display = "none"; + break; + case 'standard': + masonryBtn.style.display = "none"; + listBtn.style.display = "none"; + stdBtn.style.display = ""; + masonryView.style.display = "none"; + listView.style.display = "none"; + stdView.style.display = ""; + break; + default: + break; + } +} + +// Switch to the next mode +masonryBtn.addEventListener("click", () => { + setDisplayMode('list'); + updateDisplayMode(); +}); + +listBtn.addEventListener("click", () => { + setDisplayMode('standard'); + updateDisplayMode(); +}); + +stdBtn.addEventListener("click", () => { + setDisplayMode('masonry'); + updateDisplayMode(); +}); + + +function setMasonryView() { + // Wait for the DOM to be fully loaded + document.addEventListener("DOMContentLoaded", function () { + // Initialize Masonry + var masonryGrid = document.getElementById("masonry-view"); + var masonry = new Masonry(masonryGrid, { + percentPosition: true, + }); + + // Initialize ImagesLoaded + var imgLoad = imagesLoaded(masonryGrid); + + // When all images are loaded, relayout Masonry + imgLoad.on("always", function () { + masonry.layout(); + }); + }); +} \ No newline at end of file diff --git a/web-app/django/VIM/apps/instruments/templates/instrument_list.html b/web-app/django/VIM/apps/instruments/templates/instrument_list.html deleted file mode 100644 index 5251fae..0000000 --- a/web-app/django/VIM/apps/instruments/templates/instrument_list.html +++ /dev/null @@ -1,18 +0,0 @@ - -
- - - -