init
This commit is contained in:
27
templates/repo/clone_buttons.tmpl
Normal file
27
templates/repo/clone_buttons.tmpl
Normal file
@ -0,0 +1,27 @@
|
||||
<button class="ui basic clone button no-transition" id="repo-clone-ssh"
|
||||
data-link="{{if $.PageIsWiki}}{{$.WikiCloneLink.SSH}}{{else}}{{$.CloneLink.SSH}}{{end}}">
|
||||
SSH
|
||||
</button>
|
||||
|
||||
<input id="repo-clone-url" value="{{if $.PageIsWiki}}{{$.WikiCloneLink.SSH}}{{else}}{{$.CloneLink.SSH}}{{end}}"
|
||||
readonly>
|
||||
|
||||
<button class="ui basic icon button poping up" id="clipboard-btn" data-original="{{.i18n.Tr "repo.copy_link"}}"
|
||||
data-success="{{.i18n.Tr "repo.copy_link_success"}}" data-error="{{.i18n.Tr "repo.copy_link_error"}}"
|
||||
data-content="{{.i18n.Tr "repo.copy_link"}}" data-variation="inverted tiny"
|
||||
data-clipboard-target="#repo-clone-url">
|
||||
Copy
|
||||
</button>
|
||||
|
||||
{{if not (and $.DisableHTTP $.DisableSSH)}}
|
||||
<script defer>
|
||||
const isSSH = true
|
||||
const sshButton = document.getElementById('repo-clone-ssh');
|
||||
const input = document.getElementById('repo-clone-url');
|
||||
if (input) input.value = sshButton.dataset.link;
|
||||
if (sshButton) sshButton.classList['add']('primary');
|
||||
setTimeout(() => {
|
||||
if (sshButton) sshButton.classList.remove('no-transition');
|
||||
}, 100);
|
||||
</script>
|
||||
{{end}}
|
151
templates/repo/course_view_list.tmpl
Normal file
151
templates/repo/course_view_list.tmpl
Normal file
@ -0,0 +1,151 @@
|
||||
<table id="repo-files-table" class="ui single line table">
|
||||
<thead>
|
||||
<tr class="commit-list">
|
||||
<th>
|
||||
{{if .LatestCommitUser}}
|
||||
{{ctx.AvatarUtils .LatestCommitUser 24}}
|
||||
{{if .LatestCommitUser.FullName}}
|
||||
<a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{.LatestCommitUser.FullName}}</strong></a>
|
||||
{{else}}
|
||||
<a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a>
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{if .LatestCommit.Author}}
|
||||
{{ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24}}
|
||||
<strong>{{.LatestCommit.Author.Name}}</strong>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
</th>
|
||||
<th>{{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }}
|
||||
{{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses "root" $}}
|
||||
<span class="grey commit-summary" title="{{.LatestCommit.Summary}}"><span
|
||||
class="message-wrapper">{{RenderCommitMessageLinkSubject .LatestCommit.Message $.RepoLink $commitLink $.Repository.ComposeMetas}}</span>
|
||||
{{if IsMultilineCommitMessage .LatestCommit.Message}}
|
||||
<button class="basic compact mini ui icon button commit-button"><i
|
||||
class="ellipsis horizontal icon"></i></button>
|
||||
<pre class="commit-body"
|
||||
style="display: none;">{{RenderCommitBody .LatestCommit.Message $.RepoLink $.Repository.ComposeMetas}}</pre>
|
||||
{{end}}
|
||||
</span>
|
||||
</th>
|
||||
<th id="total"></th>
|
||||
<th class="text grey right age">{{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{if .HasParentPath}}
|
||||
<tr class="has-parent">
|
||||
<td colspan="3">{{svg "octicon-reply"}}<a href="{{$.BranchLink}}{{.ParentPath}}">..</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{range $item := .Files}}
|
||||
{{$entry := $item.Entry}}
|
||||
{{$commit := $item.Commit}}
|
||||
{{$subModuleFile := $item.SubModuleFile}}
|
||||
<tr>
|
||||
<td class="name four wide">
|
||||
<span class="truncate">
|
||||
{{if $entry.IsSubModule}}
|
||||
{{svg "octicon-file-submodule"}}
|
||||
{{$refURL := $subModuleFile.RefURL AppUrl $.Repository.FullName $.SSHDomain}}
|
||||
{{if $refURL}}
|
||||
<a href="{{$refURL}}">{{$entry.Name}}</a><span class="at">@</span><a
|
||||
href="{{$refURL}}/commit/{{$subModuleFile.RefID}}">{{ShortSha $subModuleFile.RefID}}</a>
|
||||
{{else}}
|
||||
{{$entry.Name}}<span class="at">@</span>{{ShortSha $subModuleFile.RefID}}
|
||||
{{end}}
|
||||
{{else}}
|
||||
{{if $entry.IsDir}}
|
||||
{{$subJumpablePathName := $entry.GetSubJumpablePathName}}
|
||||
{{svg "octicon-file-directory-fill"}}
|
||||
<a class="muted" href="{{$.TreeLink}}/{{PathEscapeSegments $subJumpablePathName}}" title="{{$subJumpablePathName}}">
|
||||
{{$subJumpablePathFields := StringUtils.Split $subJumpablePathName "/"}}
|
||||
{{$subJumpablePathFieldLast := (Eval (len $subJumpablePathFields) "-" 1)}}
|
||||
{{if eq $subJumpablePathFieldLast 0}}
|
||||
{{$subJumpablePathName}}
|
||||
{{else}}
|
||||
{{$subJumpablePathPrefixes := slice $subJumpablePathFields 0 $subJumpablePathFieldLast}}
|
||||
<span class="text light-2">{{StringUtils.Join $subJumpablePathPrefixes "/"}}</span>/{{index $subJumpablePathFields $subJumpablePathFieldLast}}
|
||||
{{end}}
|
||||
</a>
|
||||
{{else}}
|
||||
{{svg (printf "octicon-%s" (EntryIcon $entry))}}
|
||||
<a href="{{$.TreeLink}}/{{$entry.Name}}"
|
||||
title="{{$entry.Name}}">{{$entry.Name}}</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</span>
|
||||
</td>
|
||||
<td class="message five wide">
|
||||
<span class="truncate">
|
||||
<a href="{{$.RepoLink}}/commit/{{$commit.ID}}"
|
||||
title="{{$commit.Summary}}">{{$commit.Summary | RenderEmoji}}</a>
|
||||
</span>
|
||||
</td>
|
||||
<td class="message four wide center centered">
|
||||
<span style="display: none;" class="ui basic label" id="{{$entry.Name}}">
|
||||
</span>
|
||||
</td>
|
||||
<td class="text right age three wide">{{TimeSince $commit.Committer.When $.Lang}}</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
{{if .ReadmeExist}}
|
||||
{{template "repo/view_file" .}}
|
||||
{{end}}
|
||||
<script>
|
||||
if (!("{{.Name}}" === "tutors" || "{{.Name}}" === "template")) {
|
||||
fetch(COURSES_URL + "/courses/{{$.Repository.Owner.Name}}/{{$.Repository.Name}}/exercises", {
|
||||
referrerPolicy: "origin",
|
||||
credentials: "include",
|
||||
redirect: 'follow'
|
||||
}).then(res => {
|
||||
if (!res.ok) {
|
||||
if (res.status === 401) {
|
||||
const form = document.createElement("form")
|
||||
form.action = "/user/logout"
|
||||
form.method = "POST"
|
||||
document.body.appendChild(form);
|
||||
form.submit()
|
||||
}
|
||||
} else {
|
||||
res.text().then(res => {
|
||||
let json = JSON.parse(res)
|
||||
let total = document.getElementById("total")
|
||||
total.innerText = json["total"] + " / " + json["max_total"] + " (" + json["percentage"] + "%)"
|
||||
for (let [name, info] of Object.entries(json["exercises"])) {
|
||||
let el = document.getElementById(name)
|
||||
if (el !== null) {
|
||||
if (info["finished"]) {
|
||||
if (info["points"] !== null) {
|
||||
el.innerText = info["points"].toString() + " / " + info["max_points"].toString()
|
||||
el.classList.add("black")
|
||||
} else {
|
||||
el.innerText = "grading in process"
|
||||
el.classList.add("black")
|
||||
}
|
||||
} else {
|
||||
el.innerText = info["message"]
|
||||
if (info["important_message"]) {
|
||||
el.classList.add("red")
|
||||
}
|
||||
}
|
||||
el.style.removeProperty("display")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(_ => {
|
||||
{{if .IsAdmin}}
|
||||
{{else}}
|
||||
const form = document.createElement("form")
|
||||
form.action = "/user/logout"
|
||||
form.method = "POST"
|
||||
document.body.appendChild(form);
|
||||
form.submit()
|
||||
{{end}}
|
||||
})
|
||||
}
|
||||
</script>
|
69
templates/repo/header.tmpl
Normal file
69
templates/repo/header.tmpl
Normal file
@ -0,0 +1,69 @@
|
||||
<div class="header-wrapper">
|
||||
{{with .Repository}}
|
||||
<div class="ui container">
|
||||
<div class="repo-header">
|
||||
<div class="repo-title-wrap df fc mb-4">
|
||||
<div class="repo-title">
|
||||
<a href="{{AppSubUrl}}/{{.Owner.Name}}" id="repo_owner">{{.Owner.FullName}}</a>
|
||||
<div class="mx-2" style="display: none" id="slash">/</div>
|
||||
<a href="{{$.RepoLink}}" id="repo_name" style="display: none">{{.Name}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ui labeled button mb-4" data-position="top center" data-variation="tiny" tabindex="0">
|
||||
<a class="ui compact small basic button disabled" id="tutor">
|
||||
Tutor
|
||||
</a>
|
||||
<a class="ui basic label disabled" id="tutor_name">
|
||||
Not found
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- end grid -->
|
||||
</div><!-- end container -->
|
||||
<div class="ui tabs divider"></div>
|
||||
<script>
|
||||
function no_course_repo() {
|
||||
document.getElementById("slash").style.removeProperty("display")
|
||||
document.getElementById("repo_name").style.removeProperty("display")
|
||||
document.getElementById("repo_owner").innerText = "{{.Owner.Name}}"
|
||||
document.getElementById("tutor").style.display = "none"
|
||||
document.getElementById("tutor_name").style.display = "none"
|
||||
setTimeout(function () {
|
||||
document.getElementById("builds").style.display = "none"
|
||||
document.getElementById("chat").style.display = "none"
|
||||
}, 1)
|
||||
}
|
||||
|
||||
if ("{{.Name}}" === "tutors" || "{{.Name}}" === "template") {
|
||||
no_course_repo()
|
||||
} else {
|
||||
|
||||
fetch(COURSES_URL + "/courses/{{.Owner.Name}}/{{.Name}}/tutor", {
|
||||
referrerPolicy: "origin",
|
||||
credentials: "include"
|
||||
}).then(res => {
|
||||
if (!res.ok) {
|
||||
if (res.status === 401) {
|
||||
const form = document.createElement("form")
|
||||
form.action = "/user/logout"
|
||||
form.method = "POST"
|
||||
document.body.appendChild(form);
|
||||
form.submit()
|
||||
} else if (res.status === 500) {
|
||||
no_course_repo()
|
||||
}
|
||||
} else {
|
||||
res.text().then(res => {
|
||||
let tutor = JSON.parse(res)
|
||||
let el = document.getElementById("tutor_name")
|
||||
el.innerText = tutor["name"]
|
||||
el.setAttribute("href", "/" + tutor["username"])
|
||||
el.classList.remove("disabled")
|
||||
})
|
||||
}
|
||||
}).catch(_ => {
|
||||
no_course_repo()
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{{end}}
|
124
templates/repo/home.tmpl
Normal file
124
templates/repo/home.tmpl
Normal file
@ -0,0 +1,124 @@
|
||||
{{template "base/head" .}}
|
||||
{{ $n := len .TreeNames}}
|
||||
{{$l := Eval $n "-" 1}}
|
||||
<div class="page-content repository file list {{if .IsBlame}}blame{{end}}">
|
||||
{{template "repo/header" .}}
|
||||
<div class="ui container {{if .IsBlame}}fluid padded{{end}}">
|
||||
{{template "base/alert" .}}
|
||||
{{if and .Permission.IsAdmin (not .Repository.IsArchived)}}
|
||||
<div class="ui repo-topic-edit grid form" id="topic_edit" style="display:none">
|
||||
<div class="fourteen wide column">
|
||||
<div class="field">
|
||||
<div class="ui fluid multiple search selection dropdown">
|
||||
<input type="hidden" name="topics"
|
||||
value="{{range $i, $v := .Topics}}{{.Name}}{{if lt (Eval $i "+" 1) (len $.Topics)}},{{end}}{{end}}">
|
||||
{{range .Topics}}
|
||||
<div class="ui small label topic transition visible" data-value="{{.Name}}"
|
||||
style="display: inline-block !important; cursor: default;">{{.Name}}{{svg "octicon-x" 16 "delete icon ml-3 mt-1"}}</div>
|
||||
{{end}}
|
||||
<div class="text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .Repository.IsArchived}}
|
||||
<div class="ui warning message">
|
||||
{{.i18n.Tr "repo.archive.title"}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins">
|
||||
{{if eq $n 0}}
|
||||
<div class="left fitted item mr-0">
|
||||
<div class="ui tiny primary buttons">
|
||||
{{if .Permission.IsAdmin}}
|
||||
<a class="ui button" href="{{.RepoLink}}/settings">
|
||||
{{.i18n.Tr "repo.settings"}}
|
||||
</a>
|
||||
{{end}}
|
||||
<a class="ui button" target="_blank" id="builds">
|
||||
Builds
|
||||
</a>
|
||||
<a class="ui button" href="{{.RepoLink}}/commits/branch/master">
|
||||
Commits
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section"
|
||||
href="{{.RepoLink}}/src/{{.BranchNameSubURL}}"
|
||||
title="{{.Repository.Name}}">{{StringUtils.EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span
|
||||
class="divider">/</span>{{if eq $i $l}}<span class="active section"
|
||||
title="{{$v}}">{{StringUtils.EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}
|
||||
<span class="section"><a href="{{$.BranchLink}}/{{$p}}"
|
||||
title="{{$v}}">{{StringUtils.EllipsisString $v 30}}</a></span>{{end}}{{end}}</span>
|
||||
</div>
|
||||
{{end}}
|
||||
<!-- If home page, show new PR. If not, show breadcrumb -->
|
||||
<div class="right fitted item mr-0" id="file-buttons">
|
||||
<div class="ui tiny primary buttons">
|
||||
{{if .Repository.CanEnableEditor}}
|
||||
{{if .CanAddFile}}
|
||||
<a href="{{.RepoLink}}/_new/{{.BranchName}}/{{.TreePath}}"
|
||||
class="ui button">
|
||||
{{.i18n.Tr "repo.editor.new_file"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{if .CanUploadFile}}
|
||||
<a href="{{.RepoLink}}/_upload/{{.BranchName}}/{{.TreePath}}"
|
||||
class="ui button">
|
||||
{{.i18n.Tr "repo.editor.upload_file"}}
|
||||
</a>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{if and (ne $n 0) (not .IsViewFile) (not .IsBlame) }}
|
||||
<a href="{{.RepoLink}}/commits/{{.BranchNameSubURL}}/{{.TreePath}}"
|
||||
class="ui button">
|
||||
{{.i18n.Tr "repo.file_history"}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="fitted item">
|
||||
<!-- Only show clone panel in repository home page -->
|
||||
{{if eq $n 0}}
|
||||
<div class="ui action tiny input" id="clone-panel">
|
||||
{{template "repo/clone_buttons" .}}
|
||||
<button id="download-btn" class="ui basic jump dropdown icon button poping up"
|
||||
data-content="{{.i18n.Tr "repo.download_archive"}}" data-variation="tiny inverted"
|
||||
data-position="top right">
|
||||
{{svg "octicon-download"}}
|
||||
<div class="menu">
|
||||
<a class="item archive-link"
|
||||
data-url="{{$.RepoLink}}/archive/{{$.BranchName}}.zip">{{svg "octicon-file-zip"}}
|
||||
{{.i18n.Tr "repo.download_zip"}}</a>
|
||||
<a class="item archive-link"
|
||||
data-url="{{$.RepoLink}}/archive/{{$.BranchName}}.tar.gz">{{svg "octicon-file-zip"}}
|
||||
{{.i18n.Tr "repo.download_tar"}}</a>
|
||||
<a class="item archive-link"
|
||||
data-url="{{$.RepoLink}}/archive/{{$.BranchName}}.bundle">{{svg "octicon-package"}}
|
||||
{{.i18n.Tr "repo.download_bundle"}}</a>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{if .IsViewFile}}
|
||||
{{template "repo/view_file" .}}
|
||||
{{else if .IsBlame}}
|
||||
{{template "repo/blame" .}}
|
||||
{{else}}
|
||||
{{if eq $n 0}}
|
||||
{{template "repo/course_view_list" .}}
|
||||
{{else}}
|
||||
{{template "repo/view_list" .}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{template "base/footer" .}}
|
||||
<script>
|
||||
document.getElementById("builds").setAttribute("href", BUILD_URL + "/builds/{{ .Repository.Owner.Name }}/{{.Repository.Name}}")
|
||||
</script>
|
38
templates/repo/sub_menu.tmpl
Normal file
38
templates/repo/sub_menu.tmpl
Normal file
@ -0,0 +1,38 @@
|
||||
<div class="ui segments repository-summary{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo) .LanguageStats }} repository-summary-language-stats{{end}} mt-3">
|
||||
<div class="ui segment sub-menu repository-menu">
|
||||
<div class="ui two horizontal center link list">
|
||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo)}}
|
||||
<div class="item{{if .PageIsCommits}} active{{end}}">
|
||||
<a class="ui" href="{{.RepoLink}}/commits{{if .IsViewBranch}}/branch{{else if .IsViewTag}}/tag{{else if .IsViewCommit}}/commit{{end}}/{{.BranchName}}">{{svg "octicon-history"}} <b>{{.CommitsCount}}</b> {{.i18n.Tr (ctx.Locale.TrN .i18n.Lang .CommitsCount "repo.commit" "repo.commits") }}</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="ui">{{svg "octicon-database"}} <b>{{FileSize .Repository.Size}}</b></span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{if and (.Permission.CanRead $.UnitTypeCode) (not .IsEmptyRepo) .LanguageStats }}
|
||||
<div class="ui segment sub-menu language-stats-details" style="display: none">
|
||||
<div class="ui horizontal center link list">
|
||||
{{range .LanguageStats}}
|
||||
<div class="item df ac jc">
|
||||
<i class="color-icon mr-3" style="background-color: {{ .Color }}"></i>
|
||||
<span class="bold mr-3">
|
||||
{{if eq .Language "other" }}
|
||||
{{ $.i18n.Tr "repo.language_other" }}
|
||||
{{else}}
|
||||
{{ .Language }}
|
||||
{{end}}
|
||||
</span>
|
||||
{{ .Percentage }}%
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
<a class="ui segment language-stats">
|
||||
{{range .LanguageStats}}
|
||||
<div class="bar" style="width: {{ .Percentage }}%; background-color: {{ .Color }}"> </div>
|
||||
{{end}}
|
||||
</a>
|
||||
{{end}}
|
||||
</div>
|
Reference in New Issue
Block a user