mirror of
https://github.com/agregarr/agregarr.git
synced 2026-05-03 16:39:59 -05:00
fix(linking collections): fixes name being propgated across all hubs when linking
adds tooltip to show which hubs will be linked/unlinked
This commit is contained in:
@@ -18,6 +18,33 @@ export class DefaultHubConfigService {
|
||||
const settings = getSettings();
|
||||
const hubConfigs = settings.plex.hubConfigs || [];
|
||||
|
||||
// Check if any hubs are missing linkIds (legacy hubs from before automatic linking was implemented)
|
||||
const hasHubsWithoutLinkIds = hubConfigs.some(
|
||||
(hub) => hub.linkId === undefined && hubConfigs.length > 1
|
||||
);
|
||||
|
||||
// If we have multiple hubs and some are missing linkIds, apply automatic linking and save
|
||||
if (hasHubsWithoutLinkIds) {
|
||||
logger.info(
|
||||
'Detected hubs without linkIds - applying automatic linking to repair legacy hubs',
|
||||
{
|
||||
label: 'Default Hub Config Service',
|
||||
totalHubs: hubConfigs.length,
|
||||
}
|
||||
);
|
||||
|
||||
const linkedConfigs = this.applyAutomaticLinking(hubConfigs);
|
||||
settings.plex.hubConfigs = linkedConfigs;
|
||||
settings.save();
|
||||
|
||||
logger.info('Automatic linking applied to legacy hubs', {
|
||||
label: 'Default Hub Config Service',
|
||||
linkedGroups: this.countLinkedGroups(linkedConfigs),
|
||||
});
|
||||
|
||||
return linkedConfigs;
|
||||
}
|
||||
|
||||
return hubConfigs;
|
||||
}
|
||||
|
||||
@@ -28,6 +55,7 @@ export class DefaultHubConfigService {
|
||||
const settings = getSettings();
|
||||
|
||||
// Preserve existing isActive status when updating hub configs
|
||||
// Also repairs any broken names from the linking bug (names are refreshed from Plex discovery data)
|
||||
const existingHubConfigs = settings.plex.hubConfigs || [];
|
||||
const mergedHubConfigs = newConfigs.map(
|
||||
(newConfig: DiscoveredHubConfig) => {
|
||||
@@ -36,12 +64,30 @@ export class DefaultHubConfigService {
|
||||
existing.hubIdentifier === newConfig.hubIdentifier &&
|
||||
existing.libraryId === newConfig.libraryId
|
||||
);
|
||||
|
||||
// Check if name is being corrected (for logging)
|
||||
const nameChanged =
|
||||
existingConfig && existingConfig.name !== newConfig.name;
|
||||
if (nameChanged) {
|
||||
logger.info(
|
||||
`Correcting hub name from "${existingConfig.name}" to "${newConfig.name}"`,
|
||||
{
|
||||
label: 'Default Hub Config Service',
|
||||
hubIdentifier: newConfig.hubIdentifier,
|
||||
libraryId: newConfig.libraryId,
|
||||
oldName: existingConfig.name,
|
||||
newName: newConfig.name,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...newConfig,
|
||||
// Preserve existing ID or generate new one
|
||||
id: existingConfig?.id || IdGenerator.generateId(),
|
||||
// Preserve existing isActive status, or default to true for new configs
|
||||
isActive: existingConfig?.isActive ?? true,
|
||||
// Note: name comes from newConfig (discovery data), which fixes any broken names from the linking bug
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -144,8 +190,17 @@ export class DefaultHubConfigService {
|
||||
// For linked collections, preserve library-specific fields
|
||||
libraryId: configToUpdate.libraryId, // Don't change the library assignment
|
||||
libraryName: configToUpdate.libraryName, // Don't change the library name
|
||||
name: configToUpdate.name, // Don't change the hub display name (library-specific)
|
||||
hubIdentifier: configToUpdate.hubIdentifier, // Don't change the hub identifier
|
||||
mediaType: configToUpdate.mediaType, // Don't change the media type
|
||||
sortOrderHome: configToUpdate.sortOrderHome, // Library-specific ordering
|
||||
sortOrderLibrary: configToUpdate.sortOrderLibrary, // Library-specific ordering
|
||||
isLibraryPromoted: configToUpdate.isLibraryPromoted, // Library-specific promotion status
|
||||
everLibraryPromoted: configToUpdate.everLibraryPromoted, // Library-specific promotion history
|
||||
isPromotedToHub: configToUpdate.isPromotedToHub, // Library-specific promotability
|
||||
missing: configToUpdate.missing, // Library-specific existence status
|
||||
lastSyncedAt: configToUpdate.lastSyncedAt, // Library-specific sync timestamp
|
||||
needsSync: configToUpdate.needsSync, // Library-specific sync status
|
||||
// Note: isLinked, linkId, isUnlinked come from settings spread above
|
||||
};
|
||||
|
||||
@@ -177,6 +232,7 @@ export class DefaultHubConfigService {
|
||||
const existingHubConfigs = settings.plex.hubConfigs || [];
|
||||
|
||||
// Add isActive field and default time restrictions server-side
|
||||
// Also repairs any broken names from the linking bug (names are refreshed from Plex discovery data)
|
||||
const hubConfigsWithActiveStatus = newConfigs.map(
|
||||
(config: DiscoveredHubConfig) => {
|
||||
// Try to find existing hub by natural key to preserve ID
|
||||
@@ -186,6 +242,22 @@ export class DefaultHubConfigService {
|
||||
existing.libraryId === config.libraryId
|
||||
);
|
||||
|
||||
// Check if name is being corrected (for logging)
|
||||
const nameChanged =
|
||||
existingConfig && existingConfig.name !== config.name;
|
||||
if (nameChanged) {
|
||||
logger.info(
|
||||
`Correcting hub name from "${existingConfig.name}" to "${config.name}"`,
|
||||
{
|
||||
label: 'Default Hub Config Service',
|
||||
hubIdentifier: config.hubIdentifier,
|
||||
libraryId: config.libraryId,
|
||||
oldName: existingConfig.name,
|
||||
newName: config.name,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...config,
|
||||
// Preserve existing ID or generate new one
|
||||
@@ -194,6 +266,7 @@ export class DefaultHubConfigService {
|
||||
timeRestriction: config.timeRestriction || {
|
||||
alwaysActive: true, // Default to always active
|
||||
},
|
||||
// Note: name comes from config (discovery data), which fixes any broken names from the linking bug
|
||||
};
|
||||
}
|
||||
);
|
||||
@@ -264,11 +337,13 @@ export class DefaultHubConfigService {
|
||||
);
|
||||
|
||||
// Link all hubs in this group
|
||||
// BUT: respect isUnlinked flag - don't re-link deliberately unlinked hubs
|
||||
hubs.forEach((hub: PlexHubConfig) => {
|
||||
resultConfigs.push({
|
||||
...hub,
|
||||
isLinked: true,
|
||||
isLinked: hub.isUnlinked ? false : true, // Don't re-link if deliberately unlinked
|
||||
linkId,
|
||||
// Keep isUnlinked as-is - it remains true if user deliberately unlinked
|
||||
});
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -186,6 +186,8 @@ export class DiscoveryService {
|
||||
await this.resetPreExistingPromotionStatus();
|
||||
|
||||
// STEP 3: Discover hubs and enhance pre-existing collections with hub data
|
||||
// Use an object to pass repairedHubNamesCount by reference so it can be modified
|
||||
const repairedHubNamesCounter = { count: 0 };
|
||||
await this.discoverHubsAndEnhance(
|
||||
plexClient,
|
||||
libraries,
|
||||
@@ -197,7 +199,9 @@ export class DiscoveryService {
|
||||
existingCollectionKeys,
|
||||
existingCollectionIds,
|
||||
allCollections,
|
||||
enhancedExistingConfigs
|
||||
enhancedExistingConfigs,
|
||||
existingHubConfigs,
|
||||
repairedHubNamesCounter
|
||||
);
|
||||
|
||||
// STEP 4: Promote collections that should be visible but aren't in hub management
|
||||
@@ -286,21 +290,31 @@ export class DiscoveryService {
|
||||
|
||||
// STEP 4: Update settings with discovered configs if requested
|
||||
if (updateSettings) {
|
||||
// Add discovered hub configs to settings
|
||||
// Add discovered hub configs to settings using DefaultHubConfigService
|
||||
// This ensures automatic linking is applied properly
|
||||
if (discoveredHubConfigs.length > 0) {
|
||||
const existingHubConfigs = settings.plex.hubConfigs || [];
|
||||
const newHubConfigs = [...existingHubConfigs];
|
||||
const { defaultHubConfigService } = await import(
|
||||
'@server/lib/collections/services/DefaultHubConfigService'
|
||||
);
|
||||
|
||||
for (const discoveredHub of discoveredHubConfigs) {
|
||||
// Add isActive: true to make it a complete PlexHubConfig
|
||||
newHubConfigs.push({ ...discoveredHub, isActive: true });
|
||||
}
|
||||
// Use appendConfigs which applies automatic linking logic
|
||||
// This also saves the repaired names from existing hubs
|
||||
defaultHubConfigService.appendConfigs(discoveredHubConfigs);
|
||||
|
||||
settings.plex.hubConfigs = newHubConfigs;
|
||||
logger.debug(
|
||||
`Added ${discoveredHubConfigs.length} new hub configs to settings`,
|
||||
logger.info(
|
||||
`Added ${discoveredHubConfigs.length} new hub configs to settings with automatic linking`,
|
||||
{
|
||||
label: 'Discovery Service',
|
||||
repairedNamesCount: repairedHubNamesCounter.count,
|
||||
}
|
||||
);
|
||||
} else if (repairedHubNamesCounter.count > 0) {
|
||||
// No new hubs, but we repaired existing hub names - save settings
|
||||
settings.save();
|
||||
logger.info(
|
||||
`Repaired ${repairedHubNamesCounter.count} existing hub names (no new hubs discovered)`,
|
||||
{
|
||||
label: 'Discovery Service - Name Repair',
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -715,7 +729,9 @@ export class DiscoveryService {
|
||||
existingCollectionKeys: Set<string>,
|
||||
existingCollectionIds: Set<string>,
|
||||
allCollections: PlexCollection[],
|
||||
enhancedExistingConfigs: PreExistingCollectionConfig[]
|
||||
enhancedExistingConfigs: PreExistingCollectionConfig[],
|
||||
existingHubConfigs: PlexHubConfig[],
|
||||
repairedHubNamesCounter: { count: number }
|
||||
): Promise<void> {
|
||||
// Counters for summary logging
|
||||
let skippedAgregarrCollections = 0;
|
||||
@@ -898,6 +914,28 @@ export class DiscoveryService {
|
||||
if (!existingHubKeys.has(hubKey)) {
|
||||
discoveredHubConfigs.push(hubConfig);
|
||||
processedHubs++;
|
||||
} else {
|
||||
// Hub already exists - check if name needs repair (from linking bug)
|
||||
const existingHub = existingHubConfigs.find(
|
||||
(h: PlexHubConfig) =>
|
||||
h.hubIdentifier === hubConfig.hubIdentifier &&
|
||||
h.libraryId === hubConfig.libraryId
|
||||
);
|
||||
if (existingHub && existingHub.name !== hubConfig.name) {
|
||||
logger.info(
|
||||
`Repairing hub name from "${existingHub.name}" to "${hubConfig.name}"`,
|
||||
{
|
||||
label: 'Discovery Service - Name Repair',
|
||||
hubIdentifier: hubConfig.hubIdentifier,
|
||||
libraryId: hubConfig.libraryId,
|
||||
oldName: existingHub.name,
|
||||
newName: hubConfig.name,
|
||||
}
|
||||
);
|
||||
// Update the existing hub's name directly
|
||||
existingHub.name = hubConfig.name;
|
||||
repairedHubNamesCounter.count++;
|
||||
}
|
||||
}
|
||||
} else if (parsedHub.ratingKey) {
|
||||
// This has a rating key - check if it's an Agregarr collection or pre-existing
|
||||
|
||||
Reference in New Issue
Block a user