feat: update versions table (#6502)

* feat: add new versions table, move environments column to be feature flag toggled, and add header/cell class props to Table.vue

* feat: implement much better table column widths

* feat: update version filter control to use multiselect

* feat: implement clicking table row to go to version

* feat: mobile pass on versions table

* feat: use multiselect for platform, and fix game version show all versions when dont exist

* pnpm prepr

* feat: replace dashboard projects table with new table

* feat: update projects so its out of card

* fix: version actions buttons column width

* feat: implement overflow on loaders cell

* update platform and version width

* feat: update project icon

* feat: change edit links to use floating action bar

* pnpm prepr
This commit is contained in:
Truman Gao
2026-06-29 15:01:07 +00:00
committed by GitHub
parent fc3e384f54
commit b0c6a06909
39 changed files with 1251 additions and 1143 deletions
@@ -5,16 +5,15 @@
:game-versions="gameVersions"
:versions="versions"
:project="project"
:show-environment-column="themeStore.featureFlags.show_version_environment_column"
:version-link="(version) => buildProjectHref(`/project/${project.id}/version/${version.id}`)"
>
<template #actions="{ version }">
<ButtonStyled circular type="transparent">
<ButtonStyled circular type="transparent" color="green">
<button
v-tooltip="`Install`"
:class="{
'group-hover:!bg-brand group-hover:[&>svg]:!text-brand-inverted':
!installed || version.id !== installedVersion,
}"
v-tooltip="
!installed ? 'Install' : version.id !== installedVersion ? 'Swap version' : ''
"
:disabled="installing || (installed && version.id === installedVersion)"
@click.stop="() => install(version.id)"
>
@@ -26,7 +25,6 @@
<ButtonStyled circular type="transparent">
<OverflowMenu
v-if="false"
class="group-hover:!bg-button-bg"
:options="[
{
id: 'install-elsewhere',
@@ -52,7 +50,6 @@
<a
v-else
v-tooltip="`Open in browser`"
class="group-hover:!bg-button-bg"
:href="`https://modrinth.com/${project.project_type}/${project.slug}/version/${version.id}`"
target="_blank"
>
@@ -77,6 +74,9 @@ import { useRoute } from 'vue-router'
import { SwapIcon } from '@/assets/icons/index.js'
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
import { useTheming } from '@/store/theme.ts'
const themeStore = useTheming()
defineProps({
project: {
+1
View File
@@ -8,6 +8,7 @@ export const DEFAULT_FEATURE_FLAGS = {
worlds_tab: false,
worlds_in_home: true,
server_project_qa: false,
show_version_environment_column: false,
server_ram_as_bytes_always_on: false,
always_show_app_controls: false,
skip_non_essential_warnings: false,
@@ -21,6 +21,7 @@ export const DEFAULT_FEATURE_FLAGS = validateValues({
developerMode: false,
demoMode: false,
showVersionFilesInTable: false,
showVersionEnvironmentColumn: false,
showAdsWithPlus: false,
alwaysShowChecklistAsPopup: true,
testTaxForm: false,
@@ -914,18 +914,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "يرجى مراجعة بيانات تعريف البيئة"
},
"dashboard.projects.sort.ascending": {
"message": "صعوداً"
},
"dashboard.projects.sort.descending": {
"message": "نزولا"
},
"dashboard.projects.sort.option.name": {
"message": "الإسم"
},
"dashboard.projects.sort.option.status": {
"message": "الحالة"
},
"dashboard.revenue.available-now": {
"message": "متاح الآن"
},
@@ -1346,9 +1346,6 @@
"dashboard.overview.notifications.loading": {
"message": "Načítání oznámení..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Více projektů můžete upravit najednou jejich výběrem níže."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverové projekty nepodporují hromadné úpravy"
},
@@ -1400,24 +1397,6 @@
"dashboard.projects.project.moderator-message-aria": {
"message": "Projekt má zprávu od moderátorů. Další informace zobrazíte v projektu."
},
"dashboard.projects.sort.ascending": {
"message": "Vzestupně"
},
"dashboard.projects.sort.descending": {
"message": "Sestupně"
},
"dashboard.projects.sort.option.name": {
"message": "Jméno"
},
"dashboard.projects.sort.option.status": {
"message": "Stav"
},
"dashboard.projects.sort.option.type": {
"message": "Typ"
},
"dashboard.projects.table.icon": {
"message": "Ikona"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Benachrichtigungen werden geladen..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Du kannst mehrere Projekte gleichzeitig bearbeiten, indem du sie unten auswählst."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverprojekte understützen Massenbearbeitung nicht"
},
@@ -1712,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Bitte überprüfe die Umgebungsmetadaten"
},
"dashboard.projects.sort.ascending": {
"message": "Aufsteigend"
},
"dashboard.projects.sort.descending": {
"message": "Absteigend"
},
"dashboard.projects.sort.option.name": {
"message": "Name"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Art"
},
"dashboard.projects.table.icon": {
"message": "Icon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Benachrichtigungen werden geladen..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Du kannst mehrere Projekte gleichzeitig bearbeiten, indem du sie unten auswählst."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverprojekte unterstützen Massenbearbeitung nicht"
},
@@ -1712,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Bitte überprüfe die Umgebungsmetadaten"
},
"dashboard.projects.sort.ascending": {
"message": "Aufsteigend"
},
"dashboard.projects.sort.descending": {
"message": "Absteigend"
},
"dashboard.projects.sort.option.name": {
"message": "Name"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Typ"
},
"dashboard.projects.table.icon": {
"message": "Icon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
+7 -19
View File
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Loading notifications..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "You can edit multiple projects at once by selecting them below."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Server projects do not support bulk editing"
},
@@ -1712,23 +1709,11 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Please review environment metadata"
},
"dashboard.projects.sort.ascending": {
"message": "Ascending"
"dashboard.projects.selection-bar.aria-label": {
"message": "Selected projects actions"
},
"dashboard.projects.sort.descending": {
"message": "Descending"
},
"dashboard.projects.sort.option.name": {
"message": "Name"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Type"
},
"dashboard.projects.table.icon": {
"message": "Icon"
"dashboard.projects.selection-bar.selected-count": {
"message": "{count, plural, one {# project selected} other {# projects selected}}"
},
"dashboard.projects.table.id": {
"message": "ID"
@@ -1736,6 +1721,9 @@
"dashboard.projects.table.name": {
"message": "Name"
},
"dashboard.projects.table.select-all-bulk-editable": {
"message": "Select all projects that support bulk editing"
},
"dashboard.projects.table.status": {
"message": "Status"
},
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Cargando notificaciones..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Puedes editar varios proyectos a la vez seleccionándolos a continuación."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Los proyectos no son compatible con la edición masiva de servidores"
},
@@ -1712,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Por favor revisa los metadatos de entorno"
},
"dashboard.projects.sort.ascending": {
"message": "Ascendente"
},
"dashboard.projects.sort.descending": {
"message": "Descendente"
},
"dashboard.projects.sort.option.name": {
"message": "Nombre"
},
"dashboard.projects.sort.option.status": {
"message": "Estado"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Icono"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1517,9 +1517,6 @@
"dashboard.overview.notifications.loading": {
"message": "Cargando notificaciones..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Puedes editar múltiples proyectos a la vez seleccionándolos abajo."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Proyectos de servidor no soportan edición masiva"
},
@@ -1592,24 +1589,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Por favor revise el entorno del metadata"
},
"dashboard.projects.sort.ascending": {
"message": "Ascendiendo"
},
"dashboard.projects.sort.descending": {
"message": "Descendiendo"
},
"dashboard.projects.sort.option.name": {
"message": "Nombre"
},
"dashboard.projects.sort.option.status": {
"message": "Estado"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Icono"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -611,24 +611,6 @@
"dashboard.projects.project.icon-alt": {
"message": "Kuvake projektille {title}"
},
"dashboard.projects.sort.ascending": {
"message": "Nouseva"
},
"dashboard.projects.sort.descending": {
"message": "Laskeva"
},
"dashboard.projects.sort.option.name": {
"message": "Nimi"
},
"dashboard.projects.sort.option.status": {
"message": "Tila"
},
"dashboard.projects.sort.option.type": {
"message": "Tyyppi"
},
"dashboard.projects.table.icon": {
"message": "Kuvake"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -998,18 +998,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Pakisuri sa metadata sa environment"
},
"dashboard.projects.sort.option.name": {
"message": "Pangalan"
},
"dashboard.projects.sort.option.status": {
"message": "Estado"
},
"dashboard.projects.sort.option.type": {
"message": "Uri"
},
"dashboard.projects.table.icon": {
"message": "Ikono"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Chargement des notifications..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Vous pouvez modifier plusieurs projets en même temps en les sélectionnant ci-dessous."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Les projets du serveur ne prennent pas en charge l'édition en masse"
},
@@ -1712,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Merci de revoir les métadonnées environnementales"
},
"dashboard.projects.sort.ascending": {
"message": "Ascendant"
},
"dashboard.projects.sort.descending": {
"message": "Descendant"
},
"dashboard.projects.sort.option.name": {
"message": "Nom"
},
"dashboard.projects.sort.option.status": {
"message": "Statut"
},
"dashboard.projects.sort.option.type": {
"message": "Type"
},
"dashboard.projects.table.icon": {
"message": "Icône"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1382,9 +1382,6 @@
"dashboard.overview.notifications.loading": {
"message": "Értesítések betöltése..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Több projektet is szerkeszthetsz egyszerre, ha kiválasztod őket alább."
},
"dashboard.projects.empty": {
"message": "Még nincsenek projektjeid. Kattints a fenti zöld gombra a kezdéshez."
},
@@ -1445,24 +1442,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Kérlek ellenőrizd a környezeti metaadatokat"
},
"dashboard.projects.sort.ascending": {
"message": "Növekvő"
},
"dashboard.projects.sort.descending": {
"message": "Csökkenő"
},
"dashboard.projects.sort.option.name": {
"message": "Név"
},
"dashboard.projects.sort.option.status": {
"message": "Állapot"
},
"dashboard.projects.sort.option.type": {
"message": "Típus"
},
"dashboard.projects.table.icon": {
"message": "Ikon"
},
"dashboard.projects.table.id": {
"message": "Azonosító"
},
@@ -1628,9 +1628,6 @@
"dashboard.overview.notifications.loading": {
"message": "Caricando le notifiche..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Puoi modificare più progetti contemporaneamente selezionandoli qui sotto."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Non puoi modificare più server contemporaneamente"
},
@@ -1703,24 +1700,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Si prega di rivedere i metadati d'ambiente"
},
"dashboard.projects.sort.ascending": {
"message": "Crescente"
},
"dashboard.projects.sort.descending": {
"message": "Decrescente"
},
"dashboard.projects.sort.option.name": {
"message": "Nome"
},
"dashboard.projects.sort.option.status": {
"message": "Stato"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Icona"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1211,9 +1211,6 @@
"dashboard.overview.notifications.loading": {
"message": "通知を読み込み中…"
},
"dashboard.projects.bulk-edit-hint": {
"message": "以下で選択することで、複数のプロジェクトを一括で編集できます。"
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "サーバープロジェクトでは一括編集を利用できません"
},
@@ -1286,24 +1283,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "環境メタデータを確認してください"
},
"dashboard.projects.sort.ascending": {
"message": "昇順"
},
"dashboard.projects.sort.descending": {
"message": "降順"
},
"dashboard.projects.sort.option.name": {
"message": "名前"
},
"dashboard.projects.sort.option.status": {
"message": "ステータス"
},
"dashboard.projects.sort.option.type": {
"message": "種類"
},
"dashboard.projects.table.icon": {
"message": "アイコン"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -998,9 +998,6 @@
"dashboard.overview.notifications.loading": {
"message": "알림 불러오는 중..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "아래에서 여러 프로젝트를 선택하면 한 번에 편집할 수 있습니다."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "서버 프로젝트는 일괄 편집을 지원하지 않습니다"
},
@@ -1070,24 +1067,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "환경 메타데이터를 검토해 주세요"
},
"dashboard.projects.sort.ascending": {
"message": "오름차순"
},
"dashboard.projects.sort.descending": {
"message": "내림차순"
},
"dashboard.projects.sort.option.name": {
"message": "이름"
},
"dashboard.projects.sort.option.status": {
"message": "상태"
},
"dashboard.projects.sort.option.type": {
"message": "유형"
},
"dashboard.projects.table.icon": {
"message": "아이콘"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1367,9 +1367,6 @@
"dashboard.overview.notifications.loading": {
"message": "Sedang memuat pemberitahuan..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Anda boleh menyunting berbilang projek sekaligus dengan memilihnya di bawah."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Projek pelayan tidak menyokong penyuntingan pukal"
},
@@ -1439,24 +1436,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Sila semak metadata persekitaran"
},
"dashboard.projects.sort.ascending": {
"message": "Menaik"
},
"dashboard.projects.sort.descending": {
"message": "Menurun"
},
"dashboard.projects.sort.option.name": {
"message": "Nama"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Jenis"
},
"dashboard.projects.table.icon": {
"message": "Ikon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1358,9 +1358,6 @@
"dashboard.overview.notifications.loading": {
"message": "Notificaties aan het laden..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "U kunt meerdere projecten tegelijkertijd bijwerken door ze hieronder te selecteren."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Massa wijzigingen worden niet ondersteund door server projecten"
},
@@ -1412,12 +1409,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Controller project metadata alstublieft"
},
"dashboard.projects.sort.option.name": {
"message": "Naam"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.table.name": {
"message": "Naam"
},
@@ -851,9 +851,6 @@
"dashboard.organizations.title": {
"message": "Organiseringer"
},
"dashboard.projects.bulk-edit-hint": {
"message": "Du kan redigere flere prosjekt samtidig ved å velge dem nedafor."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverprosjekt støtter ikke massredigering"
},
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Ładowanie powiadomień..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Możesz edytować kilka projektów naraz, zaznaczając je poniżej."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Projekty serwerów nie wspierają grupowej edycji"
},
@@ -1709,24 +1706,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Sprawdź metadane środowiska"
},
"dashboard.projects.sort.ascending": {
"message": "Rosnąco"
},
"dashboard.projects.sort.descending": {
"message": "Malejąco"
},
"dashboard.projects.sort.option.name": {
"message": "Nazwa"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Rodzaj"
},
"dashboard.projects.table.icon": {
"message": "Ikona"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1631,9 +1631,6 @@
"dashboard.overview.notifications.loading": {
"message": "Carregando notificações..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Você pode editar vários projetos em simultâneo, selecionando-os abaixo."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Os projetos de servidor não suportam edição em massa"
},
@@ -1709,24 +1706,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Por favor, revise os metadados do ambiente"
},
"dashboard.projects.sort.ascending": {
"message": "Crescente"
},
"dashboard.projects.sort.descending": {
"message": "Decrescente"
},
"dashboard.projects.sort.option.name": {
"message": "Nome"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Ícone"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -821,18 +821,6 @@
"dashboard.projects.links.wiki-page.label": {
"message": "Página da Wiki"
},
"dashboard.projects.sort.option.name": {
"message": "Nome"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Ícone"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1628,9 +1628,6 @@
"dashboard.overview.notifications.loading": {
"message": "Загрузка уведомлений..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Можно редактировать сразу несколько проектов, выбрав их ниже."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Серверные проекты не поддерживают массовое редактирование"
},
@@ -1706,24 +1703,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Проверьте метаданные среды"
},
"dashboard.projects.sort.ascending": {
"message": "По возрастанию"
},
"dashboard.projects.sort.descending": {
"message": "По убыванию"
},
"dashboard.projects.sort.option.name": {
"message": "Название"
},
"dashboard.projects.sort.option.status": {
"message": "Статус"
},
"dashboard.projects.sort.option.type": {
"message": "Тип"
},
"dashboard.projects.table.icon": {
"message": "Иконка"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1514,24 +1514,6 @@
"dashboard.projects.project.icon-alt": {
"message": "Ikon för {title}"
},
"dashboard.projects.sort.ascending": {
"message": "Stigande"
},
"dashboard.projects.sort.descending": {
"message": "Fallande"
},
"dashboard.projects.sort.option.name": {
"message": "Namn"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Typ"
},
"dashboard.projects.table.icon": {
"message": "Ikon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1574,9 +1574,6 @@
"dashboard.overview.notifications.loading": {
"message": "Bildirimler yükleniyor..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Aşağıdan seçerek birden fazla projeyi düzenleyebilirsiniz."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Sunucu projeleri toplu düzenlemeyi desteklemez"
},
@@ -1652,24 +1649,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Lütfen ortam meta verilerini inceleyin"
},
"dashboard.projects.sort.ascending": {
"message": "Artan"
},
"dashboard.projects.sort.descending": {
"message": "Azalan sırada sırala"
},
"dashboard.projects.sort.option.name": {
"message": "İsim"
},
"dashboard.projects.sort.option.status": {
"message": "Durum"
},
"dashboard.projects.sort.option.type": {
"message": "Tip"
},
"dashboard.projects.table.icon": {
"message": "Simge"
},
"dashboard.projects.table.id": {
"message": "Kimlik"
},
@@ -1301,9 +1301,6 @@
"dashboard.overview.notifications.loading": {
"message": "Завантаження сповіщень…"
},
"dashboard.projects.bulk-edit-hint": {
"message": "Ви можете редагувати кілька проєктів одночасно, вибравши їх нижче."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Проєкти сервера не підтримують масове редагування"
},
@@ -1376,24 +1373,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Перегляньте метадані середовища"
},
"dashboard.projects.sort.ascending": {
"message": "Зростання"
},
"dashboard.projects.sort.descending": {
"message": "Спадання"
},
"dashboard.projects.sort.option.name": {
"message": "Назва"
},
"dashboard.projects.sort.option.status": {
"message": "Статус"
},
"dashboard.projects.sort.option.type": {
"message": "Тип"
},
"dashboard.projects.table.icon": {
"message": "Значок"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1478,9 +1478,6 @@
"dashboard.overview.notifications.loading": {
"message": "Đang tải thông báo..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Bạn có thể sửa đổi nhiều dự án cùng một lúc bằng cách chọn chúng ở dưới."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Dự án máy chủ không hỗ trợ sửa đổi nhiều mục cùng một lúc"
},
@@ -1556,24 +1553,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Vui lòng xem lại thông tin dữ liệu"
},
"dashboard.projects.sort.ascending": {
"message": "Từ dưới lên"
},
"dashboard.projects.sort.descending": {
"message": "Từ trên xuống"
},
"dashboard.projects.sort.option.name": {
"message": "Tên"
},
"dashboard.projects.sort.option.status": {
"message": "Trạng thái"
},
"dashboard.projects.sort.option.type": {
"message": "Loại"
},
"dashboard.projects.table.icon": {
"message": "B.tượng"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1631,9 +1631,6 @@
"dashboard.overview.notifications.loading": {
"message": "加载通知…"
},
"dashboard.projects.bulk-edit-hint": {
"message": "你可以通过下方复选框选择多个项目来一次性编辑。"
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "服务器项目不支持批量编辑"
},
@@ -1709,24 +1706,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "请复核运行环境元数据"
},
"dashboard.projects.sort.ascending": {
"message": "正序"
},
"dashboard.projects.sort.descending": {
"message": "降序"
},
"dashboard.projects.sort.option.name": {
"message": "名称"
},
"dashboard.projects.sort.option.status": {
"message": "状态"
},
"dashboard.projects.sort.option.type": {
"message": "类型"
},
"dashboard.projects.table.icon": {
"message": "图标"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -1634,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "正在載入通知..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "你可以透過在下方選擇專案來同時編輯多個專案。"
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "伺服器專案不支援大量編輯"
},
@@ -1712,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "請審查環境詮釋資料"
},
"dashboard.projects.sort.ascending": {
"message": "遞增"
},
"dashboard.projects.sort.descending": {
"message": "遞減"
},
"dashboard.projects.sort.option.name": {
"message": "名稱"
},
"dashboard.projects.sort.option.status": {
"message": "狀態"
},
"dashboard.projects.sort.option.type": {
"message": "類型"
},
"dashboard.projects.table.icon": {
"message": "圖示"
},
"dashboard.projects.table.id": {
"message": "ID"
},
+1 -1
View File
@@ -1017,7 +1017,7 @@
</div>
<div class="normal-page__content">
<div class="overflow-x-auto"><NavTabs :links="navLinks" replace class="mb-4" /></div>
<div class="mb-3 overflow-x-auto"><NavTabs :links="navLinks" replace class="mb-1" /></div>
<NuxtPage @on-download="triggerDownloadAnimation" @delete-version="deleteVersion" />
</div>
</div>
@@ -53,6 +53,7 @@
:project="project"
:versions="versionsWithDisplayUrl"
:show-files="flags.showVersionFilesInTable"
:show-environment-column="flags.showVersionEnvironmentColumn"
:current-member="!!currentMember"
:loaders="tags.loaders"
:game-versions="tags.gameVersions"
@@ -27,6 +27,7 @@
:project="project"
:versions="versions"
:show-files="flags.showVersionFilesInTable"
:show-environment-column="flags.showVersionEnvironmentColumn"
:current-member="!!currentMember"
:loaders="tags.loaders"
:game-versions="tags.gameVersions"
+314 -351
View File
@@ -157,181 +157,215 @@
</div>
</NewModal>
<ModalCreation ref="modal_creation" />
<section class="universal-card">
<div class="header__row">
<h2 class="header__title text-2xl">{{ formatMessage(messages.headTitle) }}</h2>
<div class="input-group">
<ButtonStyled color="brand">
<button @click="$refs.modal_creation.show($event)">
<PlusIcon />
{{ formatMessage(commonMessages.createAProjectButton) }}
</button>
</ButtonStyled>
</div>
</div>
<p v-if="projects.length < 1">
{{ formatMessage(messages.noProjectsYet) }}
</p>
<template v-else>
<p>{{ formatMessage(messages.bulkEditHint) }}</p>
<div class="input-group">
<ButtonStyled>
<button :disabled="selectedProjects.length === 0" @click="$refs.editLinksModal.show()">
<EditIcon />
{{ formatMessage(messages.editLinksButton) }}
</button>
</ButtonStyled>
<div class="push-right">
<div class="labeled-control-row">
{{ formatMessage(commonMessages.sortByLabel) }}
<Combobox
v-model="sortBy"
:searchable="false"
class="small-select"
:options="sortOptions"
@update:model-value="projects = updateSort(projects, sortBy, descending)"
/>
<ButtonStyled circular>
<button
v-tooltip="formatMessage(descending ? messages.descending : messages.ascending)"
@click="updateDescending()"
>
<SortDescIcon v-if="descending" />
<SortAscIcon v-else />
<section class="relative overflow-hidden rounded-2xl">
<Table
v-model:sort-column="sortColumn"
v-model:sort-direction="sortDirection"
:columns="projectTableColumns"
:data="sortedProjects"
row-key="id"
table-min-width="50rem"
table-layout="auto"
>
<template #header>
<div class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
<h2 class="m-0 text-2xl font-semibold text-contrast">
{{ formatMessage(messages.headTitle) }}
</h2>
<div class="flex w-full flex-wrap items-center gap-2 md:w-auto">
<ButtonStyled color="brand">
<button @click="$refs.modal_creation.show($event)">
<PlusIcon />
{{ formatMessage(commonMessages.createAProjectButton) }}
</button>
</ButtonStyled>
</div>
</div>
</div>
<div class="grid-table">
<div class="grid-table__row grid-table__header">
<div>
<Checkbox
:model-value="allBulkEditableProjectsSelected"
@update:model-value="toggleAllBulkEditableProjects()"
/>
</div>
<div>{{ formatMessage(messages.iconHeader) }}</div>
<div>{{ formatMessage(messages.nameHeader) }}</div>
<div>{{ formatMessage(messages.idHeader) }}</div>
<div>{{ formatMessage(messages.typeHeader) }}</div>
<div>{{ formatMessage(messages.statusHeader) }}</div>
<div />
</template>
<template #empty-state>
<div class="flex h-64 items-center justify-center text-secondary">
{{ formatMessage(messages.noProjectsYet) }}
</div>
<div v-for="project in projects" :key="`project-${project.id}`" class="grid-table__row">
<div>
<Checkbox
v-tooltip="getBulkEditDisabledTooltip(project)"
:disabled="isProjectBulkEditDisabled(project)"
:model-value="selectedProjects.includes(project)"
@update:model-value="toggleProjectSelection(project)"
</template>
<template #header-select>
<div v-tooltip="formatMessage(messages.selectAllBulkEditableProjects)">
<Checkbox
:model-value="allBulkEditableProjectsSelected"
@update:model-value="toggleAllBulkEditableProjects()"
/>
</div>
</template>
<template #cell-select="{ row: project }">
<div>
<Checkbox
v-tooltip="getBulkEditDisabledTooltip(project)"
:disabled="isProjectBulkEditDisabled(project)"
:model-value="isProjectSelected(project)"
@update:model-value="toggleProjectSelection(project)"
/>
</div>
</template>
<template #cell-name="{ row: project }">
<nuxt-link class="project-name-cell" :to="getProjectUrl(project)">
<span
v-tooltip="project.title"
class="flex size-6 shrink-0 items-center justify-center overflow-hidden rounded text-primary"
>
<img
v-if="project.icon_url"
:src="project.icon_url"
:alt="formatMessage(messages.projectIconAlt, { title: project.title })"
class="h-6 w-6 rounded object-cover"
/>
<BoxIcon v-else class="h-full w-full" />
</span>
<span class="project-title">
<IssuesIcon
v-if="project.moderator_message"
:aria-label="formatMessage(messages.projectModeratorMessageAriaLabel)"
/>
</div>
<div>
<nuxt-link
tabindex="-1"
:to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id
}`"
>
<Avatar
:src="project.icon_url"
aria-hidden="true"
:alt="formatMessage(messages.projectIconAlt, { title: project.title })"
no-shadow
/>
</nuxt-link>
</div>
<div>
<span class="project-title">
<IssuesIcon
v-if="project.moderator_message"
:aria-label="formatMessage(messages.projectModeratorMessageAriaLabel)"
/>
<nuxt-link
class="hover-link wrap-as-needed"
:to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id
}`"
>
{{ project.title }}
</nuxt-link>
<span class="project-title-link wrap-as-needed">
{{ project.title }}
</span>
</div>
<div>
<CopyCode :text="project.id" />
</div>
<div>
{{ formatProjectType(getProjectTypeForUrl(project.project_type, project.loaders)) }}
</div>
<div>
<ProjectStatusBadge v-if="project.status" :status="project.status" />
</div>
<div class="flex !flex-row items-center !justify-end gap-2">
<ButtonStyled
v-if="projectsWithMigrationWarning.includes(project.id)"
circular
color="orange"
</span>
</nuxt-link>
</template>
<template #cell-id="{ row: project }">
<div class="flex items-center">
<CopyCode :text="project.id" />
</div>
</template>
<template #cell-type="{ row: project }">
<div class="flex items-center">
{{ getProjectDisplayType(project) }}
</div>
</template>
<template #cell-status="{ row: project }">
<div class="flex items-center">
<ProjectStatusBadge v-if="project.status" :status="project.status" />
</div>
</template>
<template #cell-actions="{ row: project }">
<div class="flex !flex-row items-center !justify-end gap-2">
<ButtonStyled
v-if="projectsWithMigrationWarning.includes(project.id)"
circular
color="orange"
>
<nuxt-link
v-tooltip="formatMessage(messages.reviewEnvironmentMetadata)"
:to="`${getProjectUrl(project)}?showEnvironmentMigrationWarning=true`"
>
<nuxt-link
v-tooltip="formatMessage(messages.reviewEnvironmentMetadata)"
:to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id
}?showEnvironmentMigrationWarning=true`"
>
<TriangleAlertIcon />
</nuxt-link>
</ButtonStyled>
<ButtonStyled circular>
<nuxt-link
v-tooltip="formatMessage(commonMessages.settingsLabel)"
:to="`/${getProjectTypeForUrl(project.project_type, project.loaders)}/${
project.slug ? project.slug : project.id
}/settings`"
>
<SettingsIcon />
</nuxt-link>
</ButtonStyled>
</div>
<TriangleAlertIcon />
</nuxt-link>
</ButtonStyled>
<ButtonStyled circular>
<nuxt-link
v-tooltip="formatMessage(commonMessages.settingsLabel)"
:to="`${getProjectUrl(project)}/settings`"
>
<SettingsIcon />
</nuxt-link>
</ButtonStyled>
</div>
</template>
</Table>
</section>
<FloatingActionBar
:shown="selectedProjects.length > 0"
:aria-label="formatMessage(messages.selectionActionBarAriaLabel)"
hide-when-modal-open
>
<div class="flex items-center gap-0.5">
<div
class="relative h-8 shrink-0"
:style="{ width: `${selectedProjectIconStackWidth}px` }"
aria-hidden="true"
>
<div
v-for="(project, index) in visibleSelectedProjects"
:key="project.id"
v-tooltip="project.title"
class="absolute top-0 flex h-8 w-8 items-center justify-center overflow-hidden rounded-lg border-[1.5px] border-solid border-surface-3 bg-surface-4"
:style="{
left: `${index * SELECTED_PROJECT_ICON_STACK_OFFSET}px`,
zIndex: visibleSelectedProjects.length - index,
}"
>
<img
v-if="project.icon_url"
:src="project.icon_url"
:alt="formatMessage(messages.projectIconAlt, { title: project.title })"
class="h-full w-full rounded-lg object-cover"
/>
<BoxIcon v-else class="h-full w-full text-primary" />
</div>
<div
v-if="selectedProjectOverflowCount > 0"
class="absolute top-0 flex h-8 w-8 items-center justify-center rounded-lg border-[1.5px] border-solid border-surface-3 bg-surface-4 text-xs font-bold text-contrast"
:style="{
left: `${visibleSelectedProjects.length * SELECTED_PROJECT_ICON_STACK_OFFSET}px`,
zIndex: 0,
}"
>
+{{ selectedProjectOverflowCount }}
</div>
</div>
</template>
</section>
<span class="px-3 py-2 text-base font-semibold tabular-nums text-contrast">
{{ formatMessage(messages.selectedProjectsCount, { count: selectedProjects.length }) }}
</span>
<div class="mx-0.5 h-6 w-px bg-surface-5" />
<ButtonStyled type="transparent">
<button
v-tooltip="formatMessage(commonMessages.clearButton)"
class="!text-primary"
@click="clearProjectSelection()"
>
<XIcon class="cq-show-icon hidden" />
<span class="bar-label">{{ formatMessage(commonMessages.clearButton) }}</span>
</button>
</ButtonStyled>
</div>
<div class="ml-auto flex items-center gap-0.5">
<ButtonStyled color="brand">
<button v-tooltip="formatMessage(messages.editLinksButton)" @click="showEditLinksModal()">
<EditIcon />
<span class="bar-label">{{ formatMessage(messages.editLinksButton) }}</span>
</button>
</ButtonStyled>
</div>
</FloatingActionBar>
</div>
</template>
<script setup>
import {
BoxIcon,
EditIcon,
IssuesIcon,
PlusIcon,
SaveIcon,
SettingsIcon,
SortAscIcon,
SortDescIcon,
TrashIcon,
TriangleAlertIcon,
XIcon,
} from '@modrinth/assets'
import {
Avatar,
ButtonStyled,
Checkbox,
Combobox,
commonMessages,
CopyCode,
defineMessages,
FloatingActionBar,
injectNotificationManager,
IntlFormatted,
NewModal,
ProjectStatusBadge,
StyledInput,
Table,
useVIntl,
} from '@modrinth/ui'
import { formatProjectType } from '@modrinth/utils'
@@ -360,6 +394,14 @@ const messages = defineMessages({
id: 'dashboard.projects.links.button.edit',
defaultMessage: 'Edit links',
},
selectedProjectsCount: {
id: 'dashboard.projects.selection-bar.selected-count',
defaultMessage: '{count, plural, one {# project selected} other {# projects selected}}',
},
selectionActionBarAriaLabel: {
id: 'dashboard.projects.selection-bar.aria-label',
defaultMessage: 'Selected projects actions',
},
editLinksHeader: {
id: 'dashboard.projects.links.header.edit',
defaultMessage: 'Edit links',
@@ -434,34 +476,6 @@ const messages = defineMessages({
id: 'dashboard.projects.empty',
defaultMessage: "You don't have any projects yet. Click the green button above to begin.",
},
bulkEditHint: {
id: 'dashboard.projects.bulk-edit-hint',
defaultMessage: 'You can edit multiple projects at once by selecting them below.',
},
ascending: {
id: 'dashboard.projects.sort.ascending',
defaultMessage: 'Ascending',
},
descending: {
id: 'dashboard.projects.sort.descending',
defaultMessage: 'Descending',
},
sortOptionName: {
id: 'dashboard.projects.sort.option.name',
defaultMessage: 'Name',
},
sortOptionStatus: {
id: 'dashboard.projects.sort.option.status',
defaultMessage: 'Status',
},
sortOptionType: {
id: 'dashboard.projects.sort.option.type',
defaultMessage: 'Type',
},
iconHeader: {
id: 'dashboard.projects.table.icon',
defaultMessage: 'Icon',
},
nameHeader: {
id: 'dashboard.projects.table.name',
defaultMessage: 'Name',
@@ -478,6 +492,10 @@ const messages = defineMessages({
id: 'dashboard.projects.table.status',
defaultMessage: 'Status',
},
selectAllBulkEditableProjects: {
id: 'dashboard.projects.table.select-all-bulk-editable',
defaultMessage: 'Select all projects that support bulk editing',
},
projectIconAlt: {
id: 'dashboard.projects.project.icon-alt',
defaultMessage: 'Icon for {title}',
@@ -505,14 +523,9 @@ useHead({ title: () => `${formatMessage(messages.headTitle)} - Modrinth` })
const user = await useUser()
const projects = ref([])
const projectsWithMigrationWarning = ref([])
const selectedProjects = ref([])
const sortBy = ref('Name')
const sortOptions = computed(() => [
{ value: 'Name', label: formatMessage(messages.sortOptionName) },
{ value: 'Status', label: formatMessage(messages.sortOptionStatus) },
{ value: 'Type', label: formatMessage(messages.sortOptionType) },
])
const descending = ref(false)
const selectedProjectIds = ref([])
const sortColumn = ref('name')
const sortDirection = ref('asc')
const editLinks = reactive({
showAffected: false,
source: { val: '', clear: false },
@@ -522,7 +535,62 @@ const editLinks = reactive({
})
const editLinksModal = ref(null)
const modal_creation = ref(null)
const sortCollator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' })
const SELECTED_PROJECT_ICON_STACK_OFFSET = 24
const projectTableColumns = computed(() => [
{
key: 'select',
width: '3rem',
headerClass: '!text-center',
cellClass: '!overflow-visible',
},
{
key: 'name',
label: formatMessage(messages.nameHeader),
enableSorting: true,
defaultSortDirection: 'asc',
width: '22rem',
},
{
key: 'id',
label: formatMessage(messages.idHeader),
width: '13rem',
cellClass: '!overflow-visible',
},
{
key: 'type',
label: formatMessage(messages.typeHeader),
enableSorting: true,
width: '11rem',
},
{
key: 'status',
label: formatMessage(messages.statusHeader),
enableSorting: true,
width: '10rem',
cellClass: '!overflow-visible',
},
{
key: 'actions',
width: '6rem',
align: 'right',
cellClass: '!overflow-visible',
},
])
const sortedProjects = computed(() => {
const direction = sortDirection.value === 'desc' ? -1 : 1
return projects.value.slice().sort((left, right) => {
const result = sortCollator.compare(
getProjectSortValue(left, sortColumn.value),
getProjectSortValue(right, sortColumn.value),
)
return result * direction
})
})
function getLinkInputPlaceholder(clearLink, isDiscord = false) {
if (clearLink) {
@@ -545,16 +613,35 @@ const bulkEditableProjects = computed(() =>
projects.value.filter((project) => !isProjectBulkEditDisabled(project)),
)
const selectedProjects = computed(() =>
projects.value.filter((project) => selectedProjectIds.value.includes(project.id)),
)
const visibleSelectedProjects = computed(() => selectedProjects.value.slice(0, 3))
const selectedProjectOverflowCount = computed(() => Math.max(0, selectedProjects.value.length - 3))
const selectedProjectIconStackWidth = computed(() => {
if (selectedProjects.value.length === 0) return 0
return (
32 +
(visibleSelectedProjects.value.length - 1 + (selectedProjectOverflowCount.value > 0 ? 1 : 0)) *
SELECTED_PROJECT_ICON_STACK_OFFSET
)
})
const allBulkEditableProjectsSelected = computed(
() =>
bulkEditableProjects.value.length > 0 &&
bulkEditableProjects.value.every((project) => selectedProjects.value.includes(project)),
bulkEditableProjects.value.every((project) => selectedProjectIds.value.includes(project.id)),
)
function toggleAllBulkEditableProjects() {
selectedProjects.value = allBulkEditableProjectsSelected.value
selectedProjectIds.value = allBulkEditableProjectsSelected.value
? []
: bulkEditableProjects.value.slice()
: bulkEditableProjects.value.map((project) => project.id)
}
function isProjectSelected(project) {
return selectedProjectIds.value.includes(project.id)
}
function toggleProjectSelection(project) {
@@ -562,12 +649,24 @@ function toggleProjectSelection(project) {
return
}
if (selectedProjects.value.includes(project)) {
selectedProjects.value = selectedProjects.value.filter((it) => it !== project)
if (isProjectSelected(project)) {
selectedProjectIds.value = selectedProjectIds.value.filter((id) => id !== project.id)
return
}
selectedProjects.value = [...selectedProjects.value, project]
selectedProjectIds.value = [...selectedProjectIds.value, project.id]
}
function clearProjectSelection() {
selectedProjectIds.value = []
}
function showEditLinksModal() {
if (selectedProjects.value.length === 0) {
return
}
editLinksModal.value?.show()
}
function getBulkEditDisabledTooltip(project) {
@@ -578,40 +677,28 @@ function getBulkEditDisabledTooltip(project) {
return ''
}
function updateSort(list, sort, desc) {
let sortedArray = list
switch (sort) {
case 'Name':
sortedArray = list.slice().sort((a, b) => a.title.localeCompare(b.title))
break
case 'Status':
sortedArray = list.slice().sort((a, b) => {
if (a.status < b.status) return -1
if (a.status > b.status) return 1
return 0
})
break
case 'Type':
sortedArray = list.slice().sort((a, b) => {
if (a.project_type < b.project_type) return -1
if (a.project_type > b.project_type) return 1
return 0
})
break
function getProjectUrlType(project) {
return getProjectTypeForUrl(project.project_type, project.loaders)
}
function getProjectDisplayType(project) {
return formatProjectType(getProjectUrlType(project))
}
function getProjectUrl(project) {
return `/${getProjectUrlType(project)}/${project.slug ? project.slug : project.id}`
}
function getProjectSortValue(project, column) {
switch (column) {
case 'type':
return getProjectDisplayType(project)
case 'status':
return project.status ?? ''
case 'name':
default:
break
return project.title ?? ''
}
if (desc) sortedArray = sortedArray.reverse()
return sortedArray
}
function resort() {
projects.value = updateSort(projects.value, sortBy.value, descending.value)
}
function updateDescending() {
descending.value = !descending.value
resort()
}
async function bulkEditLinks() {
@@ -635,7 +722,7 @@ async function bulkEditLinks() {
text: formatMessage(messages.bulkEditSuccessText),
type: 'success',
})
selectedProjects.value = []
selectedProjectIds.value = []
editLinks.issues.val = ''
editLinks.source.val = ''
@@ -656,7 +743,7 @@ async function bulkEditLinks() {
await initUserProjects()
if (user.value?.projects) {
projects.value = updateSort(user.value.projects, 'Name', false)
projects.value = user.value.projects.slice()
// minecraft_java_server type determined from component on projectV3
projects.value = projects.value.map((project) => {
@@ -677,126 +764,20 @@ if (user.value?.projects) {
}
</script>
<style lang="scss" scoped>
.grid-table {
display: grid;
grid-template-columns:
min-content min-content minmax(min-content, 2fr)
minmax(min-content, 1fr) minmax(min-content, 1fr) minmax(min-content, 1fr) min-content;
border-radius: var(--size-rounded-sm);
overflow: hidden;
margin-top: var(--spacing-card-md);
outline: 1px solid transparent;
.grid-table__row {
display: contents;
> div {
display: flex;
flex-direction: column;
justify-content: center;
padding: var(--spacing-card-sm);
// Left edge of table
&:first-child {
padding-left: var(--spacing-card-bg);
}
// Right edge of table
&:last-child {
padding-right: var(--spacing-card-bg);
}
}
&:nth-child(2n + 1) > div {
background-color: var(--color-table-alternate-row);
}
&.grid-table__header > div {
background-color: var(--color-bg);
font-weight: bold;
color: var(--color-text-dark);
padding-top: var(--spacing-card-bg);
padding-bottom: var(--spacing-card-bg);
}
}
@media screen and (max-width: 750px) {
display: flex;
flex-direction: column;
.grid-table__row {
display: grid;
grid-template: 'checkbox icon name type settings' 'checkbox icon id status settings';
grid-template-columns:
min-content min-content minmax(min-content, 2fr)
minmax(min-content, 1fr) min-content;
:nth-child(1) {
grid-area: checkbox;
}
:nth-child(2) {
grid-area: icon;
}
:nth-child(3) {
grid-area: name;
}
:nth-child(4) {
grid-area: id;
padding-top: 0;
}
:nth-child(5) {
grid-area: type;
}
:nth-child(6) {
grid-area: status;
padding-top: 0;
}
:nth-child(7) {
grid-area: settings;
}
}
.grid-table__header {
grid-template: 'checkbox settings';
grid-template-columns: min-content minmax(min-content, 1fr);
:nth-child(2),
:nth-child(3),
:nth-child(4),
:nth-child(5),
:nth-child(6) {
display: none;
}
}
}
@media screen and (max-width: 560px) {
.grid-table__row {
display: grid;
grid-template: 'checkbox icon name settings' 'checkbox icon id settings' 'checkbox icon type settings' 'checkbox icon status settings';
grid-template-columns: min-content min-content minmax(min-content, 1fr) min-content;
:nth-child(5) {
padding-top: 0;
}
}
.grid-table__header {
grid-template: 'checkbox settings';
grid-template-columns: min-content minmax(min-content, 1fr);
}
}
.project-name-cell {
display: flex;
min-width: 0;
min-height: 3.5rem;
align-items: center;
gap: var(--spacing-card-sm);
color: inherit;
text-decoration: none;
}
.project-title {
display: flex;
flex-direction: row;
min-width: 0;
gap: var(--spacing-card-xs);
svg {
@@ -804,29 +785,11 @@ if (user.value?.projects) {
}
}
.status {
margin-top: var(--spacing-card-xs);
}
.hover-link:hover {
.project-name-cell:hover .project-title-link,
.project-name-cell:focus-visible .project-title-link {
text-decoration: underline;
}
.labeled-control-row {
flex: 1;
display: flex;
flex-direction: row;
min-width: 0;
align-items: center;
gap: var(--spacing-card-md);
white-space: nowrap;
}
.small-select {
width: -moz-fit-content;
width: fit-content;
}
.label-button[data-active='true'] {
--background-color: var(--color-red);
--text-color: var(--color-brand-inverted);