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,14 +367,18 @@ export const AssetsPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
// Find recommended assets based on user's partnerGroup matching any AssetGroup.name
|
// Find recommended assets based on user's partnerGroup matching any AssetGroup.name (supports comma-separated multiple groups)
|
||||||
const recommendedGroup = user?.partnerGroup && user.role === "PARTNER_USER"
|
const partnerGroupStrings = user?.partnerGroup && user.role === "PARTNER_USER"
|
||||||
? groups.find(g => g.name.trim().toLowerCase() === user.partnerGroup?.trim().toLowerCase())
|
? user.partnerGroup.split(',').map(s => s.trim().toLowerCase())
|
||||||
: null;
|
: [];
|
||||||
|
|
||||||
// Only recommend assets that the partner actually has permission to access
|
// Only recommend assets that the partner actually has permission to access, and deduplicate
|
||||||
const recommendedAssets = recommendedGroup
|
const recommendedAssets = partnerGroupStrings.length > 0
|
||||||
? recommendedGroup.assets.filter(recAsset =>
|
? 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)
|
assets.some(allAsset => allAsset.id === recAsset.id)
|
||||||
)
|
)
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@ -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"
|
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>
|
<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>
|
</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">
|
<span className="text-[9px] text-amber-600 font-extrabold uppercase tracking-wide">
|
||||||
Includes {pGroup} Group
|
Includes {pGroup}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
@ -988,13 +997,25 @@ export const DirectoryPage: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
/* Current Shared Assets List */
|
|
||||||
/* Current Shared Assets List */
|
/* Current Shared Assets List */
|
||||||
(() => {
|
(() => {
|
||||||
const matchedGroup = selectedPartnerForAssets?.partnerGroup
|
const matchedGroups = selectedPartnerForAssets?.partnerGroup
|
||||||
? assetGroups.find(g => g.name.trim().toLowerCase() === selectedPartnerForAssets.partnerGroup.trim().toLowerCase())
|
? selectedPartnerForAssets.partnerGroup.split(',').map((s: string) => s.trim().toLowerCase())
|
||||||
: null;
|
: [];
|
||||||
const inheritedAssets = matchedGroup ? matchedGroup.assets : [];
|
|
||||||
|
// 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 directAssets = selectedPartnerForAssets?.sharedAssets || [];
|
||||||
const totalCount = directAssets.length + inheritedAssets.length;
|
const totalCount = directAssets.length + inheritedAssets.length;
|
||||||
|
|
||||||
@ -1011,7 +1032,7 @@ export const DirectoryPage: React.FC = () => {
|
|||||||
return (
|
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">
|
<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 */}
|
{/* 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 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">
|
<div className="flex items-center gap-3 min-w-0">
|
||||||
{getFileIcon(asset.type || '', asset.title)}
|
{getFileIcon(asset.type || '', asset.title)}
|
||||||
@ -1022,12 +1043,12 @@ export const DirectoryPage: React.FC = () => {
|
|||||||
{asset.categoryId || 'General'}
|
{asset.categoryId || 'General'}
|
||||||
</span>
|
</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">
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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" />
|
<Lock className="w-4 h-4 text-ink-400" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user