feat: hook up excludes modpack

This commit is contained in:
tdgao
2026-08-14 12:55:45 -06:00
parent ee74727e36
commit 3ce9c6d7de
3 changed files with 64 additions and 25 deletions
@@ -186,14 +186,14 @@ const dependencyProjectIds = computed(() => [
),
])
const pendingProjectId = ref<string>()
const excludedProjectIds = ref(new Set<string>())
watch(dependencyProjectIds, (projectIds) => {
const selectedProjectIds = new Set(projectIds)
excludedProjectIds.value = new Set(
[...excludedProjectIds.value].filter((projectId) => selectedProjectIds.has(projectId)),
)
})
const excludedProjectIds = computed(
() =>
new Set(
selectedFilters.value
.filter((filter) => filter.type === FILTER_TYPE_ID && filter.negative)
.map((filter) => parseDependencyProjectFilterOption(filter.option).projectId),
),
)
const { data: dependentProjects } = useQuery({
queryKey: computed(() => [
@@ -226,7 +226,9 @@ const selectedProjectId = computed(() =>
? parseDependencyProjectFilterOption(selectedDependencyFilter.value.option).projectId
: undefined,
)
const showSelectedProject = computed(() => Boolean(selectedProjectId.value && selectedProject.value))
const showSelectedProject = computed(() =>
Boolean(selectedProjectId.value && selectedProject.value),
)
const dependencyTypes = computed<DependencyType[]>(() =>
selectedDependencyFilter.value
@@ -294,19 +296,15 @@ function removeIncludedProject(projectId: string) {
filter.type !== FILTER_TYPE_ID ||
parseDependencyProjectFilterOption(filter.option).projectId !== projectId,
)
const nextExcludedProjectIds = new Set(excludedProjectIds.value)
nextExcludedProjectIds.delete(projectId)
excludedProjectIds.value = nextExcludedProjectIds
}
function toggleProjectExcluded(projectId: string) {
const nextExcludedProjectIds = new Set(excludedProjectIds.value)
if (nextExcludedProjectIds.has(projectId)) {
nextExcludedProjectIds.delete(projectId)
} else {
nextExcludedProjectIds.add(projectId)
}
excludedProjectIds.value = nextExcludedProjectIds
selectedFilters.value = selectedFilters.value.map((filter) =>
filter.type === FILTER_TYPE_ID &&
parseDependencyProjectFilterOption(filter.option).projectId === projectId
? { ...filter, negative: !filter.negative }
: filter,
)
}
function resetDraftDependencyTypes() {
@@ -12,9 +12,16 @@
<XIcon />
{{
formatMessage(includedProjectsMessage, {
projects: selectedIncludedProjectItems
.map((item) => dependentProjectNames.get(item.option) ?? item.option)
.join(', '),
projects: formatProjectNames(selectedIncludedProjectItems),
})
}}
</TagItem>
<TagItem v-if="selectedExcludedProjectItems.length > 0" :action="removeExcludedProjectFilters">
<XIcon />
<BanIcon class="text-brand-red" />
{{
formatMessage(excludedProjectsMessage, {
projects: formatProjectNames(selectedExcludedProjectItems),
})
}}
</TagItem>
@@ -86,6 +93,10 @@ const includedProjectsMessage = defineMessage({
id: 'search.filter.included_projects',
defaultMessage: 'Includes: {projects}',
})
const excludedProjectsMessage = defineMessage({
id: 'search.filter.excluded_projects',
defaultMessage: 'Excludes: {projects}',
})
type Item = {
type: string
@@ -172,7 +183,16 @@ const items: ComputedRef<Item[]> = computed(() => {
const selectedItems = computed(() => items.value.filter((x) => !x.provided))
const selectedIncludedProjectItems = computed(() =>
props.projectType === 'modpack'
? selectedItems.value.filter((item) => item.type === 'compatible_dependency_project_ids')
? selectedItems.value.filter(
(item) => item.type === 'compatible_dependency_project_ids' && !item.negative,
)
: [],
)
const selectedExcludedProjectItems = computed(() =>
props.projectType === 'modpack'
? selectedItems.value.filter(
(item) => item.type === 'compatible_dependency_project_ids' && item.negative,
)
: [],
)
const otherSelectedItems = computed(() =>
@@ -181,9 +201,21 @@ const otherSelectedItems = computed(() =>
: selectedItems.value,
)
const selectedTagCount = computed(
() => otherSelectedItems.value.length + (selectedIncludedProjectItems.value.length > 0 ? 1 : 0),
() =>
otherSelectedItems.value.length +
(selectedIncludedProjectItems.value.length > 0 ? 1 : 0) +
(selectedExcludedProjectItems.value.length > 0 ? 1 : 0),
)
function formatProjectNames(items: Item[]) {
return items
.map((item) => {
const projectId = parseDependencyProjectFilterOption(item.option).projectId
return dependentProjectNames.value.get(projectId) ?? projectId
})
.join(', ')
}
function removeFilter(filter: Item) {
selectedFilters.value = selectedFilters.value.filter(
(x) => x.type !== filter.type || x.option !== filter.option,
@@ -192,7 +224,13 @@ function removeFilter(filter: Item) {
function removeIncludedProjectFilters() {
selectedFilters.value = selectedFilters.value.filter(
(filter) => filter.type !== 'compatible_dependency_project_ids',
(filter) => filter.type !== 'compatible_dependency_project_ids' || filter.negative,
)
}
function removeExcludedProjectFilters() {
selectedFilters.value = selectedFilters.value.filter(
(filter) => filter.type !== 'compatible_dependency_project_ids' || !filter.negative,
)
}
+3
View File
@@ -4049,6 +4049,9 @@
"search.filter.dependent_project.search_placeholder": {
"defaultMessage": "Search for a project..."
},
"search.filter.excluded_projects": {
"defaultMessage": "Excludes: {projects}"
},
"search.filter.included_content.exclude": {
"defaultMessage": "Exclude"
},