-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MultiselectFilter używający select z parametrem multiple #1325
Conversation
Chyba całkiem sprawnie to działa, ale za to trochę topornie wygląda i warto trochę przeorganizować ten panel z filtrami. Mój wstępny pomysł (przy którym oczywiście się nie upieram i chętnie zobaczę lepsze propozycje) byłby taki:
Co do szczegółów działania i wyglądu multiselektorów: wydaje mi się, że pierwsza pozycja o treści "-- [nazwa własności] --" słabo się broni. Dałbym nagłówek (tak, jak przy chmurach tagów), a pierwszą pozycję nazwał odpowiednio "[Wszystkie]" bądź "[Wszyscy]", można by ją też ostylować na jakąś szarą kursywę czy coś. I to, że ona może być zaznaczona, zwłaszcza razem z innymi, jest dość nielogiczne – efekt kliknięcia na nią jest sensowny taki, jaki jest, ale moim zdaniem powinna być niezaznaczalna. BTW przeszła mi przez głowę trochę niedobra na tym etapie myśl: a czym to się różni od chmury tagów? (Oprócz tego, że czyszczenie pojedynczego filtra jest wygodniejsze…) Oczywiście opiekunów jest za dużo, żeby ich prezentować w postaci chmury, ale rodzaje przedmiotów? Sam nie mam zdania, bardzo rzadko tych filtrów używam. |
Tak, też tę myśl mam. Może wystawię jeszcze jedną wersję – z użyciem chmury tagów do jedynie rodzaju przedmiotów. I chyba na tym bym zakończył wtedy zajmowanie się tym issue, wszak wciąż mam poczucie, że każde z tych podejść nie ulepsza, a raczej utrudnia korzystanie z interfejsu w większości sytuacji. |
Nie podzielam sceptycyzmu. Możliwości, już teraz, są nie gorsze niż wcześniej – pojedynczym kliknięciem, po ew. jakimś przescrollowaniu, możemy wybrać pojedynczą grupę. Zajmuje to trochę więcej miejsca, ale to nieuniknione, poza tym zazwyczaj panel filtrów mamy i tak częściowo zwinięty. Czymś, co odróżnia tagi i efekty od kategorii i właścicieli, co być może jakoś podświadomie uzasadnia inną prezentację, to to, że te pierwsze są z przedmiotami w związku wiele-do-wielu, a te drugie – określone dla nich jednoznacznie. No i są "ważniejsze" 😉 Natomiast otrzymany efekt wizualnie dalej mnie nie przekonuje (mimo że oczywiście wiernie odwzorowuje to, o czym pisałem wcześniej). Proszę poeksperymentować samemu; ja w którymś momencie jeszcze wrócę ze swoją opinią i ew. innymi sugestiami. |
No jest, ale ma też inne wady. Ale już wiem, jak będzie "najlepiej" (mam nadzieję). Jak sam Pan wyżej zauważył, te multiselecty przydałyby się też gdzie indziej, mianowicie w głosowaniu (gdzie dodatkowo jest jeszcze kontrolka semestru, za to z jakiegoś powodu nie ma przycisku "wyczyść") i ofercie (gdzie dochodzi jeszcze status propozycji). A że te układy powinny być do siebie możliwie podobne, to dla listy przedmiotów czy też prototypu planu i tak musimy zostawić wolne miejsce. Wrócmy więc do układu trzech kolumn, ale chmury tagów będą w środkowej i prawej. W lewej kolejno: nazwa (jak wcześniej), semestr (dla głosowania i oferty), status (dla oferty), ptaszek dla pierwszaków oraz przycisk czyszczenia. Semestr i status też powinny być oczywiście multiselectami. Myślę, że w ich przypadku można dać pełne trzy wiersze i bez pseudopozycji "wszystkie". Docelowo dla nich można by pomyśleć o czymś oszczędniejszym objętościowo, ale to wizja na inny PR raczej. |
zapisy/apps/enrollment/timetable/assets/components/CourseFilter.vue
Outdated
Show resolved
Hide resolved
OK, ale musimy wprowadzić jakieś sterowanie wysokością kontrolki – dla rodzaju i opiekuna lepiej dalej nie zmniejszać, dla semestru i statusu – warto. Proszę zrobić jeszcze wariant dla głosowania (czy tego nie da się jakoś wyabstrahować swoją drogą?) i sprawdzić czy nie ma niepotrzebnych importów (a chyba są, bo nagle w ogóle nie mamy zwykłych selectów). |
Nawet zabawne się okazuje, że pomimo iż te pliki CourseFilter.vue wydają się tak do siebie podobne, to dodanie
w przypadku głosowania powoduje, że w ogóle się nie wyświetlają filtry. Jest tam za to
których nie ma w dwóch pozostałych plikach CourseFilter.vue. Zatem zapewne najpierw warto by przeanalizować to zachowanie. |
58b8d05
to
1f66843
Compare
Pierwsze wrażenie działania bardzo dobre! Na szybko mam tylko jedną poprawkę do usability: filtry, które modyfikujemy, są zawsze na górze panelu filtrów, i przez to widoczne również, kiedy ten panel jest zwinięty. Dobrze byłoby, żeby były również używalne w tej sytuacji, ale niestety rozwinięta lista opcji danego "chowa się" pod "zwinięciem" panelu – co ważne, inaczej niż w przypadku obecnych dropdownów pojedynczego wyboru. Warto to dopracować. Z kolei w kwestii czepialstwa estetycznego można by nieco zwiększyć stopień pisma, jakim wyświetlane są opcje w filtrach (mógłby być taki sam, jak dla placeholderów "Wszystkie rodzaje" / "Wszyscy opiekunowie"), a trójkątne ikonki w przyciskach wydają się umieszczone nieco poniżej środka. Sądzę też, że przycisk z "iksem" do czyszczenia stanu filtra mógłby mieć jakąś ramkę i/lub tło (np. takie same jak ten z trójkątem), żeby było widać, gdzie on właściwie jest, ale tu jestem bardziej skłonny zmienić zdanie. EDIT: układ panelu filtrów w liście przedmiotów został zmieniony zgodnie z dotychczasową dyskusją, ale ona była toczona w innym kontekście, tj. kiedy filtry nowego rodzaju miały mieć wielolinijkowe kontrolki. Udało się je zrobić z kontrolkami jednolinijkowymi, więc nie ma tego powodu zmieniać układu, do którego użytkownicy są już przyzwyczajeni – przywróćmy stary. |
zapisy/apps/enrollment/timetable/assets/components/filters/MultiSelectFilter.vue
Outdated
Show resolved
Hide resolved
zapisy/apps/enrollment/timetable/assets/components/filters/MultiSelectFilter.vue
Outdated
Show resolved
Hide resolved
zapisy/apps/enrollment/timetable/assets/components/filters/MultiSelectFilter.vue
Outdated
Show resolved
Hide resolved
aa0aef1
to
12c4077
Compare
Przywróciłem poprzedni układ i wrzuciłem poprawkę związaną ze zwijaniem panelu z filtrami. |
zapisy/apps/enrollment/timetable/assets/components/CourseFilter.vue
Outdated
Show resolved
Hide resolved
Drobne podsumowanie prac: PR dodaje komponent W ramach prac zostały dość mocno zmodyfikowane style dostarczane przez bibliotekę, zatem w celu ułatwienia modyfikacji komponentu, zostały style dodane bezpośrednio do kodu źródłowego i bezpośrednio zmodyfikowane. Z racji wymogu, że dropdown komponentu musiał być widoczny poza “zwiniętymi” filtrami na stronie, właściwość |
Kiedy menu jest otwarte, a przynajmniej jeden element wybrany, wyświetlaj listę zaznaczeń zamiast domyślnego placeholdera
Ta zmiana, i to do tej „lepszej” wersji, okazała się bardzo łatwa. Efekt jest rzeczywiście intuicyjny: napis zależy teraz od tylko wyboru elementów, nie od tego, czy menu jest otwarte. |
Pozwoliłem sobie wyedytować wszystkie trzy pliki Dobrze, że najświeższa zmiana okazała się nieskomplikowana, natomiast widzę teraz potrzebę jeszcze jednej poprawki: zauważyłem, że przy powybieranych opcjach stan opisującego napisu odzwierciedla kolejność zaznaczania, co jest oczywiście dość idiotyczne. Fajnie byłoby to jakoś normalizować, być może sortując listę |
Dopisałem tę zmianę, chociaż rozwiązanie, które proponuję, nie jest najprostsze. Opis oryginalnej implementacjiZaimplementowałem to też zresztą niedoskonale, używając jako funkcji porównującej liniowego przeszukania pełnej listy. Uznałem, że taka implementacja jest najprostsza, a w przypadku tak małych list inkrementacja wykładnika złożoności nie boli, ale jeśli Pan, lub kto inny, się nie zgadza, mogę też oczywiście zaimplementować coś bardziej złożonego. Edit: niepotrzebnie się spieszyłem. Wystarczyło pomyśleć o tym jeszcze raz, żeby uświadomić sobie, że zamiast wyświetlać listę |
To z kolei dobrze, że ja się nie spieszyłem, bo miałem zamiar zaproponować zmianę właśnie w tym duchu 🙂 Teraz jest oczywiście w porządku i działa. Być może ostatnia rzecz, na którą należałoby zwrócić uwagę, to rzecz z wiadomości/wątku #1325 (comment) (plus ja muszę rozgryźć jeden bardzo techniczny szczegół) i będzie można wreszcie skończyć tę zabawę. |
6191b53
to
d863c62
Compare
Zamiast używać definicji skopiowanych z repo MultiSelect i dostosowywaniu ich, referencjonujemy domyślne style, a następnie odpowiednio nadpisujemy.
Zgodnie z naszą rozmową spróbowałem wyekstrahować różnice pomiędzy dodanym w tym PR plikiem scss a domyślnymi stylami MultiSelectFilter. |
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style> | ||
|
||
<style> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spodziewałbym się czegoś z grubsza takiego
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style> | |
<style> | |
<style lang="scss" scoped> | |
@import "~vue-multiselect/dist/vue-multiselect.min.css"; |
ale proszę samemu sprawdzić/dowiedzieć się, czy ta propozycja (uwzględniając wszystkie jej elementy) ma sens, ja bardziej zgaduję jej formę na podstawie tego, jak wyglądają inne pliki w projekcie. W szczególności nigdzie nie używamy dyrektywy @import
w plikach .vue
, więc gdyby z jakiegoś kryptycznego powodu nie działała ona tutaj, to będzie należało wywalić to do osobnego pliku .scss
(ale poza tą ewentualnością nie widzę w tym momencie takiej potrzeby, optycznie nie wygląda ta sekcja jakoś strasznie).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rzeczywiście, wygląda to lepiej i działa.
Problem jest jedynie z atrybutem "scoped": style wypisane w takim bloku nie nakładają się na te zaimportowane. Mogę więc albo usunąć ten atrybut, albo, jeśli miałoby to w czymś pomóc, zrobić dwa bloki: jeden "scoped" z importem, drugi, pozbawiony go, z całą resztą.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ciekawe, z czego to się bierze; zgaduję, że jest ortogonalne do reszty proponowanej przeze mnie zmiany – czy jeśli będą dwa osobne elementy <style>
(w "starej" bądź "nowej" formie, to już chyba nie powinno mieć znaczenia), to które z czterech możliwości nadania im tego atrybutu działają, a które nie?
Dwa bloki to oczywiście żadna herezja, jest na to nawet przykład w https://vuejs.org/api/sfc-css-features.html ale dobrze byłoby to robić wtedy, kiedy chcemy, a nie wtedy, kiedy jesteśmy do tego zmuszeni.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Zgaduję, że problem wynika wprost z semantyki atrybutu scoped
: jeśli dobrze rozumiem, to zapewnia on, że style pod nim zadeklarowane obowiązywać będą tylko w komponencie, który ten styl zawiera.
W tym przypadku: komponentem zawierającym styl jest nasz MultiSelectFilter
, ale chcemy, aby te style dotyczyły zagnieżdżonego w nim komponentu multiselect
.
Dlaczego deklaracja @import
działa ze scoped
nie rozumiem, ale być może jest jakieś znane silnikowi mapowanie pomiędzy stylami, które importujemy, a komponentem multiselect
, dzięki któremu Vue wie, że właśnie w nim powinien te style zastosować.
Po porównaniu lokalnego pliku SCSS w ostatnim stanie, w jakim istniał on osobno, i https://github.com/shentao/vue-multiselect/blob/master/src/Multiselect.vue który był podany jako punkt wyjścia do modyfikacji, widzę takie przeoczenia (które być może są celowe, ale wtedy proszę o wyjaśnienie):
Dodatkowo trochę nie podoba mi się, że wycofywanie deklaracji, które w oryginalnym stylu się nam nie podobają, odbywa się w bardzo różny sposób...
Warto byłoby uzasadnić (w komentarzach w kodzie?) te różne podejścia, a jeśli przy okazji uda się je ograniczyć, to tym lepiej. |
zapisy/apps/enrollment/timetable/assets/components/filters/MultiSelectFilter.vue
Show resolved
Hide resolved
zapisy/apps/enrollment/timetable/assets/components/filters/MultiSelectFilter.vue
Outdated
Show resolved
Hide resolved
Poruszył Pan w swoim komentarzu (o różnicach między moją wersją a tą oryginalną – zawartą w pliku SCSS) wiele wątków, na które trudno byłoby mi odpowiedzieć symetrycznie. Wydaje mi się, że to wszystko, ale nie przeczę, że coś mogło mi umknąć, bardzo proszę zapoznać się z poprawkami i komentarzami. |
(regresji spowodowanej poprzednim commitem)
Rzeczywiście, zbyt frywolnie podszedłem do usuwania kodu. Aż dziwne, że nie tego zauważyłem, pewnie to przez późną godzinę. |
…d. (#1325) Na stronach z filtrowaniem (wykazy przedmiotów oraz propozycji i wyniki głosowania na nie) zastępujemy dotychczasowy `SelectFilter` (który znika z projektu) filtrem wielokrotnego wyboru zbudowanym w oparciu o nowo dołączoną bibliotekę `vue-multiselect`. Style komponentu dostosowujemy do wyglądu SZ oraz porządkujemy kod JS w plikach wykorzystujących go (w tym uwzględniamy porządek alfabetyczny języka polskiego w _dropdownach_ z prowadzącymi). Co-authored-by: Jakub Grabarczuk <Telpenarmo@users.noreply.github.com> Co-authored-by: Bogusz Kaszowski <bkaszowski@users.noreply.github.com>
…d. (#1325) Na stronach z filtrowaniem (wykazy przedmiotów oraz propozycji i wyniki głosowania na nie) zastępujemy dotychczasowy `SelectFilter` (który znika z projektu) filtrem wielokrotnego wyboru zbudowanym w oparciu o nowo dołączoną bibliotekę `vue-multiselect`. Style komponentu dostosowujemy do wyglądu SZ oraz porządkujemy kod JS w plikach wykorzystujących go (w tym uwzględniamy porządek alfabetyczny języka polskiego w _dropdownach_ z prowadzącymi). Co-authored-by: Jakub Grabarczuk <Telpenarmo@users.noreply.github.com> Co-authored-by: Bogusz Kaszowski <bkaszowski@users.noreply.github.com>
Dodany zostaje filtr MultiselectFilter, który używa znacznika HTML select z parametrem multiple. Użyty jest dla rodzaju przedmiotu i opiekuna przedmiotu. Zapewne wypadałoby też go użyć w ofercie przedmiotów w analogicznych miejscach.
Na komputerze wybieranie wielu pozycji z listy przebiega z użyciem klawisza Ctrl. Wybranie pierwszej wartości na liście, czyli w zasadzie tytułu listy, powoduje wyzerowanie wszelkich zaznaczeń na liście. Wybranie dowolnej pozycji na liście bez klawisza Ctrl powoduje zwyczajny, pojedynczy wybór.
Closes #746.