Feat: Add multi-group support for partner recommendations, column asset counts, and detail modal lists
This commit is contained in:
parent
fa781d08f5
commit
ed60948be4
@ -367,16 +367,20 @@ export const AssetsPage = () => {
|
||||
</div>
|
||||
);
|
||||
|
||||
// Find recommended assets based on user's partnerGroup matching any AssetGroup.name
|
||||
const recommendedGroup = user?.partnerGroup && user.role === "PARTNER_USER"
|
||||
? groups.find(g => g.name.trim().toLowerCase() === user.partnerGroup?.trim().toLowerCase())
|
||||
: null;
|
||||
// Find recommended assets based on user's partnerGroup matching any AssetGroup.name (supports comma-separated multiple groups)
|
||||
const partnerGroupStrings = user?.partnerGroup && user.role === "PARTNER_USER"
|
||||
? user.partnerGroup.split(',').map(s => s.trim().toLowerCase())
|
||||
: [];
|
||||
|
||||
// Only recommend assets that the partner actually has permission to access
|
||||
const recommendedAssets = recommendedGroup
|
||||
? recommendedGroup.assets.filter(recAsset =>
|
||||
assets.some(allAsset => allAsset.id === recAsset.id)
|
||||
)
|
||||
// Only recommend assets that the partner actually has permission to access, and deduplicate
|
||||
const recommendedAssets = partnerGroupStrings.length > 0
|
||||
? groups
|
||||
.filter(g => partnerGroupStrings.includes(g.name.trim().toLowerCase()))
|
||||
.flatMap(g => g.assets)
|
||||
.filter((recAsset, index, self) =>
|
||||
self.findIndex(a => a.id === recAsset.id) === index &&
|
||||
assets.some(allAsset => allAsset.id === recAsset.id)
|
||||
)
|
||||
: [];
|
||||
|
||||
const showRecommendations =
|
||||
|
||||
@ -786,11 +786,20 @@ export const DirectoryPage: React.FC = () => {
|
||||
className="text-xs font-bold text-ink-700 hover:text-ink-950 hover:underline cursor-pointer focus:outline-none flex flex-col items-start gap-0.5"
|
||||
>
|
||||
<span>
|
||||
{((partner.sharedAssets?.length || 0) + (pGroup ? (assetGroups.find(g => g.name.trim().toLowerCase() === pGroup.trim().toLowerCase())?.assets?.length || 0) : 0))} assets
|
||||
{(() => {
|
||||
const directCount = partner.sharedAssets?.length || 0;
|
||||
if (!pGroup) return directCount;
|
||||
const pGroupNames = pGroup.split(',').map(s => s.trim().toLowerCase());
|
||||
const uniqueGroupAssetIds = new Set<string>();
|
||||
assetGroups
|
||||
.filter(g => pGroupNames.includes(g.name.trim().toLowerCase()))
|
||||
.forEach(g => g.assets.forEach(a => uniqueGroupAssetIds.add(a.id)));
|
||||
return directCount + uniqueGroupAssetIds.size;
|
||||
})()} assets
|
||||
</span>
|
||||
{pGroup && assetGroups.some(g => g.name.trim().toLowerCase() === pGroup.trim().toLowerCase()) && (
|
||||
{pGroup && assetGroups.some(g => pGroup.split(',').map(s => s.trim().toLowerCase()).includes(g.name.trim().toLowerCase())) && (
|
||||
<span className="text-[9px] text-amber-600 font-extrabold uppercase tracking-wide">
|
||||
Includes {pGroup} Group
|
||||
Includes {pGroup}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
@ -988,13 +997,25 @@ export const DirectoryPage: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
/* Current Shared Assets List */
|
||||
/* Current Shared Assets List */
|
||||
(() => {
|
||||
const matchedGroup = selectedPartnerForAssets?.partnerGroup
|
||||
? assetGroups.find(g => g.name.trim().toLowerCase() === selectedPartnerForAssets.partnerGroup.trim().toLowerCase())
|
||||
: null;
|
||||
const inheritedAssets = matchedGroup ? matchedGroup.assets : [];
|
||||
const matchedGroups = selectedPartnerForAssets?.partnerGroup
|
||||
? selectedPartnerForAssets.partnerGroup.split(',').map((s: string) => s.trim().toLowerCase())
|
||||
: [];
|
||||
|
||||
// Map inherited assets and keep track of which group name they belong to
|
||||
const inheritedAssetsMap = new Map<string, { asset: any, groupName: string }>();
|
||||
assetGroups
|
||||
.filter(g => matchedGroups.includes(g.name.trim().toLowerCase()))
|
||||
.forEach(g => {
|
||||
g.assets.forEach(asset => {
|
||||
if (!inheritedAssetsMap.has(asset.id)) {
|
||||
inheritedAssetsMap.set(asset.id, { asset, groupName: g.name });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const inheritedAssets = Array.from(inheritedAssetsMap.values());
|
||||
const directAssets = selectedPartnerForAssets?.sharedAssets || [];
|
||||
const totalCount = directAssets.length + inheritedAssets.length;
|
||||
|
||||
@ -1011,7 +1032,7 @@ export const DirectoryPage: React.FC = () => {
|
||||
return (
|
||||
<div className="border border-ink-200 rounded-xl overflow-hidden divide-y divide-ink-200 bg-ink-0 max-h-[350px] overflow-y-auto">
|
||||
{/* Group Inherited Assets */}
|
||||
{inheritedAssets.map((asset: any) => (
|
||||
{inheritedAssets.map(({ asset, groupName }) => (
|
||||
<div key={`group-asset-${asset.id}`} className="flex items-center justify-between p-3 hover:bg-ink-100 transition-colors font-sans">
|
||||
<div className="flex items-center gap-3 min-w-0">
|
||||
{getFileIcon(asset.type || '', asset.title)}
|
||||
@ -1022,12 +1043,12 @@ export const DirectoryPage: React.FC = () => {
|
||||
{asset.categoryId || 'General'}
|
||||
</span>
|
||||
<span className="text-[8px] px-1.5 py-0.2 rounded bg-amber-500/10 border border-amber-500/20 text-amber-700 font-extrabold uppercase tracking-wider">
|
||||
Inherited ({selectedPartnerForAssets?.partnerGroup})
|
||||
Inherited ({groupName})
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-1.5 text-ink-400 cursor-not-allowed shrink-0 ml-4" title="Inherited via group permissions (Read-only)">
|
||||
<div className="p-1.5 text-ink-400 cursor-not-allowed shrink-0 ml-4" title={`Inherited via ${groupName} permissions (Read-only)`}>
|
||||
<Lock className="w-4 h-4 text-ink-400" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user