Update SendFilesModal.vue
This commit is contained in:
@@ -69,21 +69,33 @@
|
|||||||
<p>{{ t('sendFilesModal.noConnectionsFound') }}</p>
|
<p>{{ t('sendFilesModal.noConnectionsFound') }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="space-y-3">
|
<div v-else class="space-y-3">
|
||||||
<div v-for="group in filteredGroupedConnections" :key="group.tag ? group.tag.id : 'untagged'" class="tag-group">
|
<div v-for="group in filteredGroupedConnections" :key="getGroupId(group)" class="tag-group">
|
||||||
<div class="flex items-center py-1.5">
|
<div
|
||||||
|
class="flex items-center py-1.5 cursor-pointer group"
|
||||||
|
@click="toggleTagGroupExpansion(group)"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:id="'tag-' + (group.tag ? group.tag.id : 'untagged')"
|
:id="'tag-cb-' + getGroupId(group)"
|
||||||
:checked="isTagGroupSelected(group)"
|
:checked="isTagGroupSelected(group)"
|
||||||
:indeterminate="isTagGroupIndeterminate(group)"
|
:indeterminate="isTagGroupIndeterminate(group)"
|
||||||
@change="toggleTagGroupSelection(group)"
|
@change="toggleTagGroupSelection(group)"
|
||||||
class="mr-2 h-4 w-4 rounded border-border text-primary focus:ring-primary focus:ring-offset-0 cursor-pointer"
|
@click.stop
|
||||||
|
class="mr-1.5 h-4 w-4 rounded border-border text-primary focus:ring-primary focus:ring-offset-0 cursor-pointer"
|
||||||
/>
|
/>
|
||||||
<label :for="'tag-' + (group.tag ? group.tag.id : 'untagged')" class="font-semibold text-foreground select-none cursor-pointer text-sm">
|
<i
|
||||||
|
:class="['fas', expandedTagGroups[getGroupId(group)] ? 'fa-chevron-down' : 'fa-chevron-right', 'mr-2 w-3 text-center text-text-secondary/80 group-hover:text-text-secondary transition-transform duration-150 ease-in-out']"
|
||||||
|
style="font-size: 0.75rem;"
|
||||||
|
></i>
|
||||||
|
<label
|
||||||
|
:for="'tag-cb-' + getGroupId(group)"
|
||||||
|
class="font-semibold text-foreground select-none cursor-pointer text-sm"
|
||||||
|
@click.stop
|
||||||
|
>
|
||||||
{{ group.tag ? group.tag.name : t('sendFilesModal.untaggedConnections') }} ({{ group.connections.length }})
|
{{ group.tag ? group.tag.name : t('sendFilesModal.untaggedConnections') }} ({{ group.connections.length }})
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<ul class="pl-7 space-y-0.5">
|
<ul v-show="expandedTagGroups[getGroupId(group)] ?? true" class="pl-7 space-y-0.5">
|
||||||
<li
|
<li
|
||||||
v-for="connection in group.connections"
|
v-for="connection in group.connections"
|
||||||
:key="connection.id"
|
:key="connection.id"
|
||||||
@@ -190,6 +202,22 @@ const selectedConnectionIds = ref<number[]>([]);
|
|||||||
const isLoadingConnections = ref(false);
|
const isLoadingConnections = ref(false);
|
||||||
const isLoadingTags = ref(false);
|
const isLoadingTags = ref(false);
|
||||||
|
|
||||||
|
const expandedTagGroups = ref<Record<string, boolean>>({});
|
||||||
|
|
||||||
|
const getGroupId = (group: GroupedConnection): string => {
|
||||||
|
return group.tag ? String(group.tag.id) : 'untagged';
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleTagGroupExpansion = (group: GroupedConnection) => {
|
||||||
|
const groupId = getGroupId(group);
|
||||||
|
// If state is undefined, default to true (expanded), then toggle it.
|
||||||
|
// So, if undefined, it becomes !(true) = false. If defined, it's just toggled.
|
||||||
|
// To make it default to expanded and then collapse on first click:
|
||||||
|
// expandedTagGroups.value[groupId] = !(expandedTagGroups.value[groupId] ?? true);
|
||||||
|
// To make it default to collapsed and then expand on first click (if true means expanded):
|
||||||
|
expandedTagGroups.value[groupId] = !(expandedTagGroups.value[groupId] ?? true);
|
||||||
|
};
|
||||||
|
|
||||||
// Simulate data for itemsToSend for development if not provided
|
// Simulate data for itemsToSend for development if not provided
|
||||||
const itemsToSendInternal = computed<ItemToSend[]>(() => {
|
const itemsToSendInternal = computed<ItemToSend[]>(() => {
|
||||||
if (props.itemsToSend && props.itemsToSend.length > 0) {
|
if (props.itemsToSend && props.itemsToSend.length > 0) {
|
||||||
@@ -269,19 +297,38 @@ const groupedConnections = computed<GroupedConnection[]>(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const filteredGroupedConnections = computed<GroupedConnection[]>(() => {
|
const filteredGroupedConnections = computed<GroupedConnection[]>(() => {
|
||||||
|
const baseGroups = groupedConnections.value;
|
||||||
|
|
||||||
if (!searchTerm.value.trim()) {
|
if (!searchTerm.value.trim()) {
|
||||||
return groupedConnections.value;
|
// If no search term, filter out groups that initially have no connections.
|
||||||
|
return baseGroups.filter(group => group.connections.length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lowerSearchTerm = searchTerm.value.toLowerCase();
|
const lowerSearchTerm = searchTerm.value.toLowerCase();
|
||||||
return groupedConnections.value
|
|
||||||
|
const result = baseGroups
|
||||||
.map(group => {
|
.map(group => {
|
||||||
const filteredConns = group.connections.filter(conn =>
|
const groupDisplayName = group.tag ? group.tag.name : t('sendFilesModal.untaggedConnections');
|
||||||
conn.type?.toLowerCase() === 'ssh' && // 只包括 SSH 连接
|
const isTagMatch = groupDisplayName.toLowerCase().includes(lowerSearchTerm);
|
||||||
|
|
||||||
|
const connsMatchingSearchByName = group.connections.filter(conn =>
|
||||||
conn.name.toLowerCase().includes(lowerSearchTerm)
|
conn.name.toLowerCase().includes(lowerSearchTerm)
|
||||||
|
// conn.type filtering is already handled in groupedConnections
|
||||||
);
|
);
|
||||||
return { ...group, connections: filteredConns };
|
|
||||||
|
if (isTagMatch) {
|
||||||
|
// Tag name matches. Show all connections of this group.
|
||||||
|
return { ...group, connections: group.connections };
|
||||||
|
} else if (connsMatchingSearchByName.length > 0) {
|
||||||
|
// Tag name doesn't match, but some connection names do. Show only those connections.
|
||||||
|
return { ...group, connections: connsMatchingSearchByName };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null; // Group doesn't match by tag name and has no connections matching by name
|
||||||
})
|
})
|
||||||
.filter(group => group.connections.length > 0); // 只包括仍有连接的分组
|
.filter(group => group !== null && group.connections.length > 0) as GroupedConnection[];
|
||||||
|
|
||||||
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
const isTagGroupSelected = (group: GroupedConnection): boolean => {
|
const isTagGroupSelected = (group: GroupedConnection): boolean => {
|
||||||
|
|||||||
Reference in New Issue
Block a user