Add yellow "Limited" badge to repository listings across admin panel, organization home, pinned repos, and shared repo lists. Uses eye icon to distinguish limited repos from private (lock) and public repos.
409 lines
18 KiB
Handlebars
409 lines
18 KiB
Handlebars
{{template "base/head" .}}
|
|
<div role="main" aria-label="{{.Title}}" class="page-content organization profile">
|
|
{{template "org/header" .}}
|
|
|
|
<div class="ui container">
|
|
<div class="ui mobile reversed stackable grid">
|
|
<div class="ui eleven wide column">
|
|
{{/* Profile README Section */}}
|
|
{{if .ProfileReadmeContent}}
|
|
<div id="readme_profile" class="render-content markup" data-profile-view-as-member="{{.IsViewingOrgAsMember}}">{{.ProfileReadmeContent}}</div>
|
|
{{end}}
|
|
|
|
{{/* Overview Tab Content */}}
|
|
{{if .PageIsViewOverview}}
|
|
{{if or .IsOrganizationMember .HasPublicPinnedRepos}}{{/* Pinned Repositories Section */}}
|
|
<div class="ui segment pinned-repos-section">
|
|
<h4 class="ui header tw-flex tw-items-center">
|
|
{{svg "octicon-pin" 16}} {{ctx.Locale.Tr "org.pinned_repos"}}
|
|
{{if .IsOrganizationOwner}}
|
|
<a class="tw-ml-auto ui mini button" href="{{.OrgLink}}/settings/pinned">
|
|
{{svg "octicon-gear" 14}} {{ctx.Locale.Tr "org.settings.pinned.manage"}}
|
|
</a>
|
|
{{end}}
|
|
</h4>
|
|
|
|
{{if .HasPinnedRepos}}
|
|
{{/* Ungrouped pinned repos */}}
|
|
{{if .UngroupedPinned}}
|
|
<div class="ui three stackable cards pinned-repos">
|
|
{{range .UngroupedPinned}}
|
|
{{if and .Repo (or $.IsOrganizationMember (not .Repo.IsPrivate))}}
|
|
<a class="ui card tw-flex tw-flex-col tw-relative" href="{{.Repo.Link}}">
|
|
{{if .Repo.IsPrivate}}
|
|
<div class="tw-absolute tw-top-2 tw-right-2 tw-text-grey" title="{{ctx.Locale.Tr "repo.desc.private"}}">{{svg "octicon-lock" 16}}</div>
|
|
{{else if .Repo.IsLimited}}
|
|
<div class="tw-absolute tw-top-2 tw-right-2 tw-text-yellow" title="{{ctx.Locale.Tr "repo.desc.limited"}}">{{svg "octicon-eye" 16}}</div>
|
|
{{end}}
|
|
<div class="content tw-text-center tw-flex-1">
|
|
{{if .Repo.Avatar}}
|
|
<img class="tw-inline-block tw-rounded" style="max-width: 80px; max-height: 80px; object-fit: contain;" src="{{.Repo.RelAvatarLink ctx}}" alt="">
|
|
{{else}}
|
|
<div class="tw-inline-block tw-p-4">
|
|
{{if .Repo.IsPrivate}}{{svg "octicon-lock" 48}}{{else if .Repo.IsLimited}}{{svg "octicon-eye" 48}}{{else if .Repo.IsFork}}{{svg "octicon-repo-forked" 48}}{{else if .Repo.IsMirror}}{{svg "octicon-mirror" 48}}{{else}}{{svg "octicon-repo" 48}}{{end}}
|
|
</div>
|
|
{{end}}
|
|
<div class="header tw-mt-2">{{if .Repo.DisplayTitle}}{{.Repo.DisplayTitle}}{{else}}{{.Repo.Name}}{{end}}</div>
|
|
{{if .Repo.Description}}
|
|
<div class="description text grey tw-text-sm tw-mt-1">{{.Repo.Description}}</div>
|
|
{{end}}
|
|
</div>
|
|
<div class="extra content tw-flex tw-justify-between tw-items-center">
|
|
{{if .Repo.PrimaryLanguage}}
|
|
<span>
|
|
<span class="repo-language-color" style="background-color: {{.Repo.PrimaryLanguage.Color}}"></span>
|
|
{{.Repo.PrimaryLanguage.Language}}
|
|
</span>
|
|
{{else}}
|
|
<span></span>
|
|
{{end}}
|
|
{{if .Repo.LicenseType}}
|
|
<span class="muted-links">{{svg "octicon-law" 14}} {{.Repo.LicenseType}}</span>
|
|
{{end}}
|
|
</div>
|
|
</a>
|
|
{{end}}
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Grouped pinned repos */}}
|
|
{{range .PinnedGroups}}
|
|
{{$groupRepos := index $.PinnedByGroup .ID}}
|
|
{{if $groupRepos}}
|
|
<div class="pinned-group tw-mt-4">
|
|
<h5 class="ui header tw-mb-2">
|
|
{{svg "octicon-chevron-down" 14}} {{.Name}}
|
|
</h5>
|
|
<div class="ui three stackable cards pinned-repos">
|
|
{{range $groupRepos}}
|
|
{{if and .Repo (or $.IsOrganizationMember (not .Repo.IsPrivate))}}
|
|
<a class="ui card tw-flex tw-flex-col tw-relative" href="{{.Repo.Link}}">
|
|
{{if .Repo.IsPrivate}}
|
|
<div class="tw-absolute tw-top-2 tw-right-2 tw-text-grey" title="{{ctx.Locale.Tr "repo.desc.private"}}">{{svg "octicon-lock" 16}}</div>
|
|
{{else if .Repo.IsLimited}}
|
|
<div class="tw-absolute tw-top-2 tw-right-2 tw-text-yellow" title="{{ctx.Locale.Tr "repo.desc.limited"}}">{{svg "octicon-eye" 16}}</div>
|
|
{{end}}
|
|
<div class="content tw-text-center tw-flex-1">
|
|
{{if .Repo.Avatar}}
|
|
<img class="tw-inline-block tw-rounded" style="max-width: 80px; max-height: 80px; object-fit: contain;" src="{{.Repo.RelAvatarLink ctx}}" alt="">
|
|
{{else}}
|
|
<div class="tw-inline-block tw-p-4">
|
|
{{if .Repo.IsPrivate}}{{svg "octicon-lock" 48}}{{else if .Repo.IsLimited}}{{svg "octicon-eye" 48}}{{else if .Repo.IsFork}}{{svg "octicon-repo-forked" 48}}{{else if .Repo.IsMirror}}{{svg "octicon-mirror" 48}}{{else}}{{svg "octicon-repo" 48}}{{end}}
|
|
</div>
|
|
{{end}}
|
|
<div class="header tw-mt-2">{{if .Repo.DisplayTitle}}{{.Repo.DisplayTitle}}{{else}}{{.Repo.Name}}{{end}}</div>
|
|
{{if .Repo.Description}}
|
|
<div class="description text grey tw-text-sm tw-mt-1">{{.Repo.Description}}</div>
|
|
{{end}}
|
|
</div>
|
|
<div class="extra content tw-flex tw-justify-between tw-items-center">
|
|
{{if .Repo.PrimaryLanguage}}
|
|
<span>
|
|
<span class="repo-language-color" style="background-color: {{.Repo.PrimaryLanguage.Color}}"></span>
|
|
{{.Repo.PrimaryLanguage.Language}}
|
|
</span>
|
|
{{else}}
|
|
<span></span>
|
|
{{end}}
|
|
{{if .Repo.LicenseType}}
|
|
<span class="muted-links">{{svg "octicon-law" 14}} {{.Repo.LicenseType}}</span>
|
|
{{end}}
|
|
</div>
|
|
</a>
|
|
{{end}}
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
{{end}}
|
|
{{else}}
|
|
{{if .IsOrganizationMember}}{{/* Empty state for pinned repos - members only */}}
|
|
<div class="ui placeholder segment tw-text-center">
|
|
<div class="ui icon header">
|
|
{{svg "octicon-pin" 48}}
|
|
<div class="content">
|
|
{{ctx.Locale.Tr "org.pinned_repos_empty_title"}}
|
|
<div class="sub header">
|
|
{{ctx.Locale.Tr "org.pinned_repos_empty_desc"}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{if .IsOrganizationOwner}}
|
|
<div class="tw-mt-4">
|
|
<a class="ui primary button" href="{{.OrgLink}}/settings/pinned">
|
|
{{svg "octicon-gear" 16}} {{ctx.Locale.Tr "org.settings.pinned.setup"}}
|
|
</a>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Profile README Empty State */}}
|
|
{{if and (not .ProfileReadmeContent) .IsOrganizationOwner}}
|
|
<div class="ui segment tw-mt-4">
|
|
<div class="ui placeholder segment tw-text-center">
|
|
<div class="ui icon header">
|
|
{{svg "octicon-book" 32}}
|
|
<div class="content">
|
|
{{ctx.Locale.Tr "org.profile_readme_empty_title"}}
|
|
<div class="sub header">
|
|
{{ctx.Locale.Tr "org.profile_readme_empty_desc"}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tw-mt-4">
|
|
<form action="{{.OrgLink}}/create-profile-repo" method="post">{{.CsrfTokenHtml}}<button class="ui primary button" type="submit">
|
|
{{svg "octicon-plus" 16}} {{ctx.Locale.Tr "org.create_profile_repo"}}
|
|
</button></form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Recent Activity Section */}}
|
|
{{if .RecentActivity}}
|
|
<div class="ui segment tw-mt-4">
|
|
<h4 class="ui header tw-flex tw-items-center">
|
|
{{svg "octicon-pulse" 16}} {{ctx.Locale.Tr "org.recent_activity"}}
|
|
</h4>
|
|
<div class="ui relaxed divided list">
|
|
{{range .RecentActivity}}
|
|
<div class="item">
|
|
<div class="tw-flex tw-items-center tw-gap-3">
|
|
{{if .Repo.Avatar}}
|
|
<img style="width: 32px; height: 32px; border-radius: 4px; object-fit: cover;" src="{{.Repo.RelAvatarLink ctx}}" alt="">
|
|
{{else}}
|
|
<div class="tw-w-8 tw-h-8 tw-flex tw-items-center tw-justify-center">
|
|
{{if .Repo.IsPrivate}}{{svg "octicon-lock" 20}}{{else if .Repo.IsFork}}{{svg "octicon-repo-forked" 20}}{{else if .Repo.IsMirror}}{{svg "octicon-mirror" 20}}{{else}}{{svg "octicon-repo" 20}}{{end}}
|
|
</div>
|
|
{{end}}
|
|
<div class="tw-flex-1 tw-min-w-0">
|
|
<a href="{{.Repo.Link}}" class="tw-font-semibold">{{if .Repo.DisplayTitle}}{{.Repo.DisplayTitle}}{{else}}{{.Repo.Name}}{{end}}</a>
|
|
{{if .CommitMessage}}
|
|
<p class="text grey tw-text-sm tw-truncate tw-mb-0">{{.CommitMessage}}</p>
|
|
{{end}}
|
|
</div>
|
|
<div class="tw-text-right tw-text-sm text grey tw-flex-shrink-0">
|
|
<span title="{{DateUtils.FullTime .CommitTime}}">{{DateUtils.TimeSince .CommitTime}}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
{{end}}
|
|
|
|
{{/* Repositories Tab Content */}}
|
|
{{if .PageIsViewRepositories}}
|
|
{{template "shared/repo/search" .}}
|
|
{{if and .ShowGrouping .RepoHeaders}}
|
|
{{/* Grouped View */}}
|
|
<div id="grouped-repos">
|
|
{{range .RepoHeaders}}
|
|
{{if .}}
|
|
<h4 class="ui dividing header tw-mt-4">{{.}}</h4>
|
|
{{end}}
|
|
{{$repos := index $.GroupedRepos .}}
|
|
<div class="flex-list">
|
|
{{range $repos}}
|
|
<div class="flex-item">
|
|
<div class="flex-item-leading">
|
|
{{template "repo/icon" .}}
|
|
</div>
|
|
<div class="flex-item-main">
|
|
<div class="flex-item-header">
|
|
<div class="flex-item-title">
|
|
<a class="text primary name" href="{{.Link}}">{{if .DisplayTitle}}{{.DisplayTitle}}{{else}}{{.Name}}{{end}}</a>
|
|
<span class="label-list">
|
|
{{if .IsArchived}}
|
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.archived"}}</span>
|
|
{{end}}
|
|
{{if .IsPrivate}}
|
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.private"}}</span>
|
|
{{else if .IsLimited}}
|
|
<span class="ui basic yellow label">{{ctx.Locale.Tr "repo.desc.limited"}}</span>
|
|
{{else}}
|
|
{{if .Owner.Visibility.IsPrivate}}
|
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.internal"}}</span>
|
|
{{end}}
|
|
{{end}}
|
|
{{if .IsTemplate}}
|
|
<span class="ui basic label">{{ctx.Locale.Tr "repo.desc.template"}}</span>
|
|
{{end}}
|
|
</span>
|
|
</div>
|
|
<div class="flex-item-trailing muted-links">
|
|
{{if .PrimaryLanguage}}
|
|
<span class="flex-text-inline">
|
|
<i class="color-icon tw-mr-2" style="background-color: {{.PrimaryLanguage.Color}}"></i>
|
|
{{.PrimaryLanguage.Language}}
|
|
</span>
|
|
{{end}}
|
|
<span class="flex-text-inline" aria-label="{{ctx.Locale.Tr "repo.stars"}}">{{svg "octicon-star" 16}} {{CountFmt .NumStars}}</span>
|
|
<span class="flex-text-inline" aria-label="{{ctx.Locale.Tr "repo.forks"}}">{{svg "octicon-git-branch" 16}} {{CountFmt .NumForks}}</span>
|
|
</div>
|
|
</div>
|
|
{{$description := .DescriptionHTML ctx}}
|
|
{{if or $description .LicenseType}}
|
|
<div class="flex-item-body tw-flex tw-justify-between tw-items-start tw-gap-2">
|
|
<div class="tw-flex-1">{{$description}}</div>
|
|
{{if .LicenseType}}
|
|
<span class="tw-flex tw-items-center tw-gap-1 tw-shrink-0 muted-links">
|
|
{{svg "octicon-law" 14}}
|
|
{{.LicenseType}}
|
|
</span>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
<div class="flex-item-body">{{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .UpdatedUnix}}</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{else}}
|
|
{{/* Flat View */}}
|
|
{{template "shared/repo/list" .}}
|
|
{{end}}
|
|
{{template "base/paginate" .}}
|
|
{{end}}
|
|
</div>
|
|
|
|
<div class="ui five wide column">
|
|
{{if .CanCreateOrgRepo}}
|
|
<div class="tw-flex tw-flex-wrap tw-justify-center tw-gap-x-1 tw-gap-y-2 tw-mb-4">
|
|
<a class="ui primary button tw-grow" href="{{AppSubUrl}}/repo/create?org={{.Org.ID}}">{{ctx.Locale.Tr "new_repo"}}</a>
|
|
{{if not .DisableNewPullMirrors}}
|
|
<a class="ui primary button tw-grow" href="{{AppSubUrl}}/repo/migrate?org={{.Org.ID}}&mirror=1">{{ctx.Locale.Tr "new_migrate"}}</a>
|
|
{{end}}
|
|
</div>
|
|
<div class="divider"></div>
|
|
{{end}}
|
|
|
|
{{if .ShowOrgProfileReadmeSelector}}
|
|
<div class="tw-my-4">
|
|
<div id="org-home-view-as-dropdown" class="ui dropdown jump">
|
|
{{- $viewAsRole := Iif (.IsViewingOrgAsMember) (ctx.Locale.Tr "org.members.member") (ctx.Locale.Tr "settings.visibility.public") -}}
|
|
<span class="text">{{svg "octicon-eye"}} {{ctx.Locale.Tr "org.view_as_role" $viewAsRole}}</span>
|
|
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
|
|
<div class="menu">
|
|
<a href="?view_as=public" class="item {{if not .IsViewingOrgAsMember}}selected{{end}}">
|
|
{{svg "octicon-check" 14 (Iif (not .IsViewingOrgAsMember) "" "tw-invisible")}} {{ctx.Locale.Tr "settings.visibility.public"}}
|
|
</a>
|
|
<a href="?view_as=member" class="item {{if .IsViewingOrgAsMember}}selected{{end}}">
|
|
{{svg "octicon-check" 14 (Iif .IsViewingOrgAsMember "" "tw-invisible")}} {{ctx.Locale.Tr "org.members.member"}}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="tw-my-2 text grey">
|
|
{{if .IsViewingOrgAsMember}}{{ctx.Locale.Tr "org.view_as_member_hint"}}{{else}}{{ctx.Locale.Tr "org.view_as_public_hint"}}{{end}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Organization Stats - Sidebar Card */}}
|
|
{{if .OrgStats}}
|
|
<div class="ui top attached header tw-flex">
|
|
<strong class="tw-flex-1">{{svg "octicon-graph" 16}} {{ctx.Locale.Tr "org.stats"}}</strong>
|
|
</div>
|
|
<div class="ui attached segment">
|
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
|
|
<div class="tw-text-center tw-p-3" style="border: 1px solid var(--color-secondary); border-radius: 6px;">
|
|
<div class="tw-text-2xl tw-font-bold">{{.OrgStats.TotalRepos}}</div>
|
|
<div class="text grey tw-text-xs">{{ctx.Locale.Tr "org.repositories"}}</div>
|
|
</div>
|
|
<div class="tw-text-center tw-p-3" style="border: 1px solid var(--color-secondary); border-radius: 6px;">
|
|
<div class="tw-text-2xl tw-font-bold">{{.OrgStats.TotalMembers}}</div>
|
|
<div class="text grey tw-text-xs">{{ctx.Locale.Tr "org.members"}}</div>
|
|
</div>
|
|
<div class="tw-text-center tw-p-3" style="border: 1px solid var(--color-secondary); border-radius: 6px;">
|
|
<div class="tw-text-2xl tw-font-bold">{{.OrgStats.TotalTeams}}</div>
|
|
<div class="text grey tw-text-xs">{{ctx.Locale.Tr "org.teams"}}</div>
|
|
</div>
|
|
<div class="tw-text-center tw-p-3" style="border: 1px solid var(--color-secondary); border-radius: 6px;">
|
|
<div class="tw-text-2xl tw-font-bold">{{.OrgStats.TotalStars}}</div>
|
|
<div class="text grey tw-text-xs">{{ctx.Locale.Tr "repo.stars"}}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Organization License - Sidebar Card */}}
|
|
{{if .OrgLicense}}
|
|
<div class="ui segment tw-mt-4">
|
|
<div class="tw-flex tw-items-center tw-gap-3">
|
|
{{svg "octicon-law" 24}}
|
|
<div>
|
|
<div class="tw-font-semibold">{{ctx.Locale.Tr "repo.license"}}</div>
|
|
<a href="{{.ProfileRepoLink}}/src/{{.ProfileRepo.DefaultBranch}}/LICENSE.md" class="tw-text-lg">
|
|
{{.OrgLicense}}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Members/Public Members Section */}}
|
|
{{if .IsOrganizationMember}}
|
|
{{/* Internal view - show all members */}}
|
|
{{if .NumMembers}}
|
|
<h4 class="ui top attached header tw-flex tw-mt-4">
|
|
<strong class="tw-flex-1">{{ctx.Locale.Tr "org.members"}}</strong>
|
|
<a class="text grey tw-flex tw-items-center" href="{{.OrgLink}}/members"><span>{{.NumMembers}}</span> {{svg "octicon-chevron-right"}}</a>
|
|
</h4>
|
|
<div class="ui attached segment members">
|
|
{{range .Members}}
|
|
<a href="{{.HomeLink}}" title="{{.Name}}{{if .FullName}} ({{.FullName}}){{end}}">{{ctx.AvatarUtils.Avatar . 48}}</a>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
|
|
{{/* Teams - only for members */}}
|
|
<div class="ui top attached header tw-flex tw-mt-4">
|
|
<strong class="tw-flex-1">{{ctx.Locale.Tr "org.teams"}}</strong>
|
|
<a class="text grey tw-flex tw-items-center" href="{{.OrgLink}}/teams"><span>{{.Org.NumTeams}}</span> {{svg "octicon-chevron-right"}}</a>
|
|
</div>
|
|
<div class="ui attached table segment teams">
|
|
{{range .Teams}}
|
|
<div class="item">
|
|
<a href="{{$.OrgLink}}/teams/{{.LowerName | PathEscape}}"><strong class="team-name">{{.Name}}</strong></a>
|
|
<p class="text grey">
|
|
<a class="muted" href="{{$.OrgLink}}/teams/{{.LowerName | PathEscape}}"><strong>{{.NumMembers}}</strong> {{ctx.Locale.Tr "org.lower_members"}}</a> ·
|
|
<a class="muted" href="{{$.OrgLink}}/teams/{{.LowerName | PathEscape}}/repositories"><strong>{{.NumRepos}}</strong> {{ctx.Locale.Tr "org.lower_repositories"}}</a>
|
|
</p>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
{{if .IsOrganizationOwner}}
|
|
<div class="ui bottom attached segment">
|
|
<a class="ui primary small button" href="{{.OrgLink}}/teams/new">{{ctx.Locale.Tr "org.create_new_team"}}</a>
|
|
</div>
|
|
{{end}}
|
|
{{else}}
|
|
{{/* Public view - show public members only */}}
|
|
{{if .PublicMembers}}
|
|
<h4 class="ui top attached header tw-flex tw-mt-4">
|
|
<strong class="tw-flex-1">{{ctx.Locale.Tr "org.public_members"}}</strong>
|
|
{{if .HasMorePublicMembers}}
|
|
<a class="text grey tw-flex tw-items-center" href="{{.OrgLink}}/members"><span>{{.TotalPublicMembers}}</span> {{svg "octicon-chevron-right"}}</a>
|
|
{{end}}
|
|
</h4>
|
|
<div class="ui attached segment members">
|
|
{{range .PublicMembers}}
|
|
<a href="{{.User.HomeLink}}" title="{{.User.Name}}{{if .User.FullName}} ({{.User.FullName}}){{end}}">{{ctx.AvatarUtils.Avatar .User 48}}</a>
|
|
{{end}}
|
|
</div>
|
|
{{end}}
|
|
{{end}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{{template "base/footer" .}}
|