Browse Source

Merge remote-tracking branch 'origin/V20221228' into gcu

gcu
chenyifan01 2 years ago
parent
commit
63bc4d1df9
38 changed files with 825 additions and 352 deletions
  1. +57
    -26
      models/cloudbrain.go
  2. +0
    -1
      modules/grampus/resty.go
  3. +3
    -4
      modules/modelarts/modelarts.go
  4. +3
    -0
      modules/repository/repo.go
  5. +12
    -1
      options/locale/locale_en-US.ini
  6. +12
    -1
      options/locale/locale_zh-CN.ini
  7. BIN
      public/img/login_bg_default.png
  8. +44
    -15
      routers/api/v1/repo/cloudbrain_dashboard.go
  9. +17
    -0
      routers/repo/grampus.go
  10. +1
    -1
      routers/repo/modelarts.go
  11. +14
    -0
      routers/user/auth.go
  12. +29
    -6
      services/cloudbrain/cloudbrainTask/notebook.go
  13. +10
    -0
      templates/base/footer_content.tmpl
  14. +1
    -0
      templates/explore/images.tmpl
  15. +2
    -2
      templates/repo/cloudbrain/benchmark/new.tmpl
  16. +3
    -0
      templates/repo/cloudbrain/show.tmpl
  17. +5
    -5
      templates/repo/home.tmpl
  18. +2
    -1
      templates/repo/modelarts/trainjob/para_manage.tmpl
  19. +9
    -4
      templates/repo/modelmanage/convertshowinfo.tmpl
  20. +46
    -4
      templates/user/auth/signin.tmpl
  21. +43
    -4
      templates/user/auth/signin_cloud_brain.tmpl
  22. +1
    -1
      templates/user/auth/signin_navbar.tmpl
  23. +97
    -59
      templates/user/auth/signin_phone.tmpl
  24. +45
    -0
      templates/user/auth/signin_up_img_default.tmpl
  25. +136
    -97
      templates/user/auth/signup_inner.tmpl
  26. +3
    -2
      web_src/js/components/Contributors.vue
  27. +8
    -7
      web_src/js/components/EditAboutInfo.vue
  28. +6
    -6
      web_src/js/components/EditTopics.vue
  29. +2
    -2
      web_src/js/components/Model.vue
  30. +3
    -2
      web_src/js/components/basic/editDialog.vue
  31. +61
    -60
      web_src/js/components/images/Images.vue
  32. +28
    -27
      web_src/js/components/images/adminImages.vue
  33. +10
    -10
      web_src/js/features/cloudbrainShow.js
  34. +1
    -1
      web_src/js/features/cloudrbanin.js
  35. +106
    -0
      web_src/js/features/i18nVue.js
  36. +2
    -1
      web_src/js/standalone/cloudbrainNew.js
  37. +1
    -1
      web_src/less/openi.less
  38. +2
    -1
      web_src/vuepages/pages/notebook/debug/index.vue

+ 57
- 26
models/cloudbrain.go View File

@@ -458,29 +458,32 @@ type GetImagesPayload struct {

type CloudbrainsOptions struct {
ListOptions
RepoID int64 // include all repos if empty
UserID int64
JobID string
SortType string
CloudbrainIDs []int64
JobStatus []string
JobStatusNot bool
Keyword string
Type int
JobTypes []string
VersionName string
IsLatestVersion string
JobTypeNot bool
NeedRepoInfo bool
RepoIDList []int64
BeginTime time.Time
EndTime time.Time
ComputeResource string
BeginTimeUnix int64
EndTimeUnix int64
AiCenter string
NeedDeleteInfo string
Cluster string
RepoID int64 // include all repos if empty
UserID int64
JobID string
SortType string
CloudbrainIDs []int64
JobStatus []string
JobStatusNot bool
Keyword string
Type int
JobTypes []string
VersionName string
IsLatestVersion string
JobTypeNot bool
NeedRepoInfo bool
RepoIDList []int64
BeginTime time.Time
EndTime time.Time
ComputeResource string
BeginTimeUnix int64
EndTimeUnix int64
AiCenter string
NeedDeleteInfo string
Cluster string
AccCardType string
AccCardsNum int
WorkServerNumber int
}

type TaskPod struct {
@@ -1568,7 +1571,8 @@ type CreateGrampusJobResponse struct {

type GetGrampusJobResponse struct {
GrampusResult
JobInfo GrampusJobInfo `json:"otJob"`
JobInfo GrampusJobInfo `json:"otJob"`
ExitDiagnostics string `json:"exitDiagnostics"`
}

type GrampusNotebookResponse struct {
@@ -2440,18 +2444,44 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
)
}

if opts.WorkServerNumber > 0 {
if opts.WorkServerNumber == 1 {
cond = cond.And(builder.Or(
builder.Eq{"cloudbrain.work_server_number": 0},
builder.Eq{"cloudbrain.work_server_number": 1},
builder.IsNull{"cloudbrain.work_server_number"},
))
} else {
cond = cond.And(
builder.Eq{"cloudbrain.work_server_number": opts.WorkServerNumber},
)
}
}

if opts.AccCardType != "" {
cond = cond.And(builder.Eq{"cloudbrain_spec.acc_card_type": opts.AccCardType})
}
if opts.AccCardsNum >= 0 {
cond = cond.And(builder.Eq{"cloudbrain_spec.acc_cards_num": opts.AccCardsNum})
}

var count int64
var err error
condition := "cloudbrain.user_id = `user`.id"
if len(opts.Keyword) == 0 {
count, err = sess.Unscoped().Where(cond).Count(new(Cloudbrain))
count, err = sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Join("left", "`user`", condition).
Join("left", "cloudbrain_spec", "cloudbrain.id = cloudbrain_spec.cloudbrain_id").
Count(new(CloudbrainInfo))
} else {
lowerKeyWord := strings.ToLower(opts.Keyword)

cond = cond.And(builder.Or(builder.Like{"LOWER(cloudbrain.job_name)", lowerKeyWord},
builder.Like{"LOWER(cloudbrain.display_job_name)", lowerKeyWord}, builder.Like{"`user`.lower_name", lowerKeyWord}))
count, err = sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Join("left", "`user`", condition).Count(new(CloudbrainInfo))
Join("left", "`user`", condition).
Join("left", "cloudbrain_spec", "cloudbrain.id = cloudbrain_spec.cloudbrain_id").
Count(new(CloudbrainInfo))

}

@@ -2473,6 +2503,7 @@ func CloudbrainAll(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, error) {
cloudbrains := make([]*CloudbrainInfo, 0, setting.UI.IssuePagingNum)
if err := sess.Table(&Cloudbrain{}).Unscoped().Where(cond).
Join("left", "`user`", condition).
Join("left", "cloudbrain_spec", "cloudbrain.id = cloudbrain_spec.cloudbrain_id").
Find(&cloudbrains); err != nil {
return nil, 0, fmt.Errorf("Find: %v", err)
}


+ 0
- 1
modules/grampus/resty.go View File

@@ -198,7 +198,6 @@ sendjob:
SetAuthToken(TOKEN).
SetResult(&result).
Get(HOST + urlTrainJob + "/" + jobID)

if err != nil {
return nil, fmt.Errorf("resty GetJob: %v", err)
}


+ 3
- 4
modules/modelarts/modelarts.go View File

@@ -22,9 +22,9 @@ import (
const (
//notebook

storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
AutoStopDurationMs = 4 * 60 * 60 * 1000
storageTypeOBS = "obs"
autoStopDuration = 4 * 60 * 60
AutoStopDurationMs = 4 * 60 * 60 * 1000

CodePath = "/code/"
OutputPath = "/output/"
@@ -168,7 +168,6 @@ type OrgMultiNode struct {
Node []int `json:"node"`
}


type Parameters struct {
Parameter []struct {
Label string `json:"label"`


+ 3
- 0
modules/repository/repo.go View File

@@ -139,6 +139,9 @@ func MigrateRepositoryGitData(doer, u *models.User, repo *models.Repository, opt
}

repo.IsMirror = true
if repo.Description == "" {
repo.Description = opts.Description
}
err = models.UpdateRepository(repo, false)
} else {
repo, err = CleanUpMigrateInfo(repo)


+ 12
- 1
options/locale/locale_en-US.ini View File

@@ -406,6 +406,8 @@ sspi_auth_failed = SSPI authentication failed
change_email = Change email
change_email_address = Change email address
new_email_address = New email address
openi_community_really_awesome = OpenI, Really Awesome!

[phone]
format_err=The format of phone number is wrong.
query_err=Fail to query phone number, please try again later.
@@ -1061,6 +1063,8 @@ model_rename=Duplicate model name, please modify model name.

notebook_file_not_exist=Notebook file does not exist.
notebook_select_wrong=Please select a Notebook(.ipynb) file first.
notebook_path_too_long=The total length of selected file or files path exceed 255 characters, please select a shorter path file or change the file path.
notebook_branch_name_too_long=The total length of branch or branches name exceed 255 characters, please select a file in other branch.
notebook_file_no_right=You have no right to access the Notebook(.ipynb) file.
notebook_repo_conflict=The files in different branches of the same repository can not run together.
debug_again_fail=Fail to restart debug task, please try again later.
@@ -1261,6 +1265,13 @@ modelarts.fullscreen_log_file = View in full screen
modelarts.exit_full_screen = Exit fullscreen
modelarts.no_node_right = The value of 'Amount of Compute Node' is wrong, you have no right to use the current value of 'Amount of Compute Node'.

scrolled_logs_top = You have scrolled to the top of the log
scrolled_logs_top_pls_retry = You have scrolled to the top of the log, please try again later!
scrolled_logs_bottom = You have scrolled to the bottom of the log
scrolled_logs_bottom_pls_retry = You have scrolled to the bottom of the log, please try again later!

canceled_operation = You have canceled the operation
successfully_deleted = Successfully deleted

debug_task_not_created = Debug task has not been created
train_task_not_created = Train task has not been created
@@ -1474,7 +1485,7 @@ blame = Blame
normal_view = Normal View
line = line
lines = lines
notebook_open = Open in Notebook
notebook_open = Run Online

editor.new_file = New File
editor.upload_file = Upload File


+ 12
- 1
options/locale/locale_zh-CN.ini View File

@@ -409,6 +409,8 @@ sspi_auth_failed=SSPI 认证失败
change_email=修改邮箱
change_email_address=修改邮箱地址
new_email_address=新邮箱地址
openi_community_really_awesome=启智社区 确实给力

[phone]
format_err=手机号格式错误。
query_err=查询手机号失败,请稍后再试。
@@ -1060,6 +1062,8 @@ model_rename=模型名称重复,请修改模型名称

notebook_file_not_exist=Notebook文件不存在。
notebook_select_wrong=请先选择Notebook(.ipynb)文件。
notebook_path_too_long=选择的一个或多个Notebook文件路径总长度超过255个字符,请选择路径较短的文件或调整文件路径。
notebook_branch_name_too_long=选择的一个或多个Notebook文件分支名总长度超过255个字符,请选择其他分支的文件。
notebook_file_no_right=您没有这个Notebook文件的读权限。
notebook_repo_conflict=同一个仓库的不同分支文件不能同时运行。
debug_again_fail=再次调试失败,请稍后再试。
@@ -1273,6 +1277,13 @@ modelarts.fullscreen_log_file=全屏查看
modelarts.exit_full_screen=退出全屏
modelarts.no_node_right = 计算节点数的值配置错误,您没有权限使用当前配置的计算节点数。

scrolled_logs_top = 您已翻阅至日志顶部
scrolled_logs_top_pls_retry = 您已翻阅至日志顶部,请稍后再试!
scrolled_logs_bottom = 您已翻阅至日志底部
scrolled_logs_bottom_pls_retry = 您已翻阅至日志底部,请稍后再试!

canceled_operation = 您已取消操作
successfully_deleted = 删除成功

debug_task_not_created = 未创建过调试任务
train_task_not_created = 未创建过训练任务
@@ -1492,7 +1503,7 @@ normal_view=普通视图
line=行
lines=行

notebook_open = 在Notebook中打开
notebook_open = 在线运行

editor.new_file=新建文件
editor.upload_file=上传文件


BIN
public/img/login_bg_default.png View File

Before After
Width: 1200  |  Height: 938  |  Size: 142 kB

+ 44
- 15
routers/api/v1/repo/cloudbrain_dashboard.go View File

@@ -645,7 +645,7 @@ func GetAllCloudbrainsPeriodDistribution(ctx *context.Context) {
}
}

ComputeResourceList := []string{"CPU/GPU", "NPU"}
ComputeResourceList := []string{"CPU/GPU", "NPU", "GCU"}
for _, v := range ComputeResourceList {
if _, ok := cloudBrainComputeResource[v]; !ok {
cloudBrainComputeResource[v] = 0
@@ -687,7 +687,6 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
return
}
recordBeginTime := recordCloudbrain[0].Cloudbrain.CreatedUnix
endTime := time.Now()
listType := ctx.Query("listType")
jobType := ctx.Query("jobType")
jobStatus := ctx.Query("jobStatus")
@@ -695,6 +694,33 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
aiCenter := ctx.Query("aiCenter")
needDeleteInfo := ctx.Query("needDeleteInfo")

accCardType := ctx.Query("accCardType")
accCardsNum := ctx.QueryInt("accCardsNum")
workServerNumber := ctx.QueryInt("workServerNumber")
beginTimeStr := ctx.QueryTrim("beginTime")
endTimeStr := ctx.QueryTrim("endTime")
var beginTimeUnix int64
var endTimeUnix int64
if beginTimeStr == "" || endTimeStr == "" {
beginTimeUnix = int64(recordBeginTime)
endTimeUnix = time.Now().Unix()
} else {
beginTime, err := time.ParseInLocation("2006-01-02T15:04:05", beginTimeStr, time.Local)
if err != nil {
log.Error("Can not ParseInLocation.", err)
ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
return
}
beginTimeUnix = beginTime.Unix()
endTime, err := time.ParseInLocation("2006-01-02T15:04:05", endTimeStr, time.Local)
if err != nil {
log.Error("Can not ParseInLocation.", err)
ctx.Error(http.StatusBadRequest, ctx.Tr("ParseInLocation_get_error"))
return
}
endTimeUnix = endTime.Unix()
}

if cloudBrainType == models.TypeCloudBrainOne && aiCenter == models.AICenterOfCloudBrainOne {
aiCenter = ""
}
@@ -753,18 +779,21 @@ func GetCloudbrainsDetailData(ctx *context.Context) {
Page: page,
PageSize: pageSize,
},
Keyword: keyword,
Type: cloudBrainType,
ComputeResource: listType,
JobTypeNot: jobTypeNot,
JobStatusNot: jobStatusNot,
JobStatus: jobStatuses,
JobTypes: jobTypes,
NeedRepoInfo: true,
BeginTimeUnix: int64(recordBeginTime),
EndTimeUnix: endTime.Unix(),
AiCenter: aiCenter,
NeedDeleteInfo: needDeleteInfo,
Keyword: keyword,
Type: cloudBrainType,
ComputeResource: listType,
JobTypeNot: jobTypeNot,
JobStatusNot: jobStatusNot,
JobStatus: jobStatuses,
JobTypes: jobTypes,
NeedRepoInfo: true,
BeginTimeUnix: beginTimeUnix,
EndTimeUnix: endTimeUnix,
AiCenter: aiCenter,
NeedDeleteInfo: needDeleteInfo,
AccCardType: accCardType,
AccCardsNum: accCardsNum,
WorkServerNumber: workServerNumber,
})
if err != nil {
ctx.ServerError("Get job failed:", err)
@@ -1039,7 +1068,7 @@ func getCloudbrainCount(beginTime time.Time, endTime time.Time, cloudbrains []*m
}
}

ComputeResourceList := []string{"CPU/GPU", "NPU"}
ComputeResourceList := []string{"CPU/GPU", "NPU", "GCU"}
for _, v := range ComputeResourceList {
if _, ok := cloudBrainComputeResource[v]; !ok {
cloudBrainComputeResource[v] = 0


+ 17
- 0
routers/repo/grampus.go View File

@@ -1375,6 +1375,23 @@ func GrampusGetLog(ctx *context.Context) {
})
return
}
result, err := grampus.GetJob(jobID)
if err != nil {
log.Error("GetJob(%s) failed:%v", job.JobName, err)
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobName": job.JobName,
"Content": content,
"CanLogDownload": false,
})
return
}
if result != nil {
job.Status = grampus.TransTrainJobStatus(result.JobInfo.Status)
if job.Status == models.GrampusStatusFailed {
content = content + "\n" + result.ExitDiagnostics
}
}

canLogDownload := err == nil && job.IsUserHasRight(ctx.User)
ctx.JSON(http.StatusOK, map[string]interface{}{
"JobName": job.JobName,


+ 1
- 1
routers/repo/modelarts.go View File

@@ -483,7 +483,7 @@ func getFileUrl(url string, filename string) string {
}
}

return url + middle + filename
return url + middle + filename + "?reset"
}

func NotebookRestart(ctx *context.Context) {


+ 14
- 0
routers/user/auth.go View File

@@ -36,6 +36,7 @@ import (
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/services/externalaccount"
"code.gitea.io/gitea/services/mailer"
"code.gitea.io/gitea/services/repository"

"gitea.com/macaron/captcha"
"github.com/markbates/goth"
@@ -145,6 +146,11 @@ func checkAutoLogin(ctx *context.Context) bool {
return false
}

func getActivityTpl() string {
result, _ := repository.RecommendContentFromPromote(setting.RecommentRepoAddr + "/signin/activity_tpl")
return result
}

// SignIn render sign in page
func SignIn(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")
@@ -168,6 +174,7 @@ func SignIn(ctx *context.Context) {
ctx.Data["PageIsLogin"] = true
ctx.Data["EnableSSPI"] = models.IsSSPIEnabled()
ctx.Data["EnableCloudBrain"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignIn)
}
@@ -185,6 +192,7 @@ func SignInCloudBrain(ctx *context.Context) {
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsCloudBrainLogin"] = true
ctx.Data["EnableCloudBrain"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignInCloudBrain)
}
@@ -197,6 +205,7 @@ func SignInPhone(ctx *context.Context) {
}

ctx.Data["PageIsPhoneLogin"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignInPhone)
}
@@ -206,6 +215,7 @@ func SignInPhonePost(ctx *context.Context, form auth.PhoneNumberCodeForm) {
ctx.Data["PageIsPhoneLogin"] = true
ctx.Data["IsCourse"] = ctx.QueryBool("course")
ctx.Data["EnableCloudBrain"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

if ctx.HasError() {
ctx.HTML(200, tplSignInPhone)
@@ -356,6 +366,7 @@ func SignInPostCommon(ctx *context.Context, form auth.SignInForm) {
func SignInCloudBrainPost(ctx *context.Context, form auth.SignInForm) {
ctx.Data["PageIsCloudBrainLogin"] = true
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login/cloud_brain"
ctx.Data["ActivityTpl"] = getActivityTpl()
SignInPostCommon(ctx, form)
}

@@ -363,6 +374,7 @@ func SignInCloudBrainPost(ctx *context.Context, form auth.SignInForm) {
func SignInPost(ctx *context.Context, form auth.SignInForm) {
ctx.Data["PageIsLogin"] = true
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["ActivityTpl"] = getActivityTpl()
SignInPostCommon(ctx, form)
}

@@ -1257,6 +1269,7 @@ func SignUp(ctx *context.Context) {

//Show Disabled Registration message if DisableRegistration or AllowOnlyExternalRegistration options are true
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration
ctx.Data["ActivityTpl"] = getActivityTpl()

ctx.HTML(200, tplSignUp)
}
@@ -1272,6 +1285,7 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["PageIsSignUp"] = true
ctx.Data["ActivityTpl"] = getActivityTpl()

//Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true
if setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration {


+ 29
- 6
services/cloudbrain/cloudbrainTask/notebook.go View File

@@ -46,6 +46,14 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_select_wrong")))
return
}
if len(getBootFile(option.File, option.OwnerName, option.ProjectName)) > 255 {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_path_too_long")))
return
}
if len(option.BranchName) > 255 {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("repo.notebook_branch_name_too_long")))
return
}

isNotebookFileExist, _ := isNoteBookFileExist(ctx, option)
if !isNotebookFileExist {
@@ -105,14 +113,29 @@ func FileNotebookCreate(ctx *context.Context, option api.CreateFileNotebookJobOp
err = downloadCode(sourceRepo, getCodePath(noteBook.JobName, sourceRepo), option.BranchName)
if err != nil {
log.Error("download code failed", err)
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
return
if !strings.Contains(err.Error(), "already exists and is not an empty directory") {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.load_code_failed")))
return
}
}
}
if !isRepoFileMatch(option, noteBook) {
noteBook.BootFile += ";" + getBootFile(option.File, option.OwnerName, option.ProjectName)
noteBook.BranchName += ";" + option.BranchName
noteBook.Description += ";" + getDescription(option)
if len(noteBook.BootFile)+len(getBootFile(option.File, option.OwnerName, option.ProjectName))+1 <= 255 {
noteBook.BootFile += ";" + getBootFile(option.File, option.OwnerName, option.ProjectName)
} else {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.notebook_path_too_long")))
return
}
if len(noteBook.BranchName)+len(option.BranchName)+1 <= 255 {
noteBook.BranchName += ";" + option.BranchName
} else {
ctx.JSON(http.StatusOK, models.BaseErrorMessageApi(ctx.Tr("cloudbrain.notebook_branch_name_too_long")))
return
}

if len(noteBook.Description)+len(getDescription(option))+1 <= 256 {
noteBook.Description += ";" + getDescription(option)
}

err := models.UpdateJob(noteBook)
if err != nil {
@@ -417,7 +440,7 @@ func cloudBrainFileNoteBookCreate(ctx *context.Context, option api.CreateFileNot
}

func getCloudbrainType(optionType int) int {
if optionType < 1 {
if optionType <= GPUType {
return models.TypeCloudBrainOne
}
if setting.ModelartsCD.Enabled {


+ 10
- 0
templates/base/footer_content.tmpl View File

@@ -1,3 +1,13 @@
<style>
@media only screen and (max-width: 767px) {
.mobile-text-align-center {
text-align: center !important;
}
.mobile-justify-content-center {
justify-content: center !important;
}
}
</style>
<footer style="border-top:none;">
<div class="ui container">
<div class="ui grid">


+ 1
- 0
templates/explore/images.tmpl View File

@@ -1,4 +1,5 @@
{{template "base/head" .}}
<div class="alert"></div>
<div id="images"></div>
<!-- 确认模态框 -->
<div id="deletemodel">


+ 2
- 2
templates/repo/cloudbrain/benchmark/new.tmpl View File

@@ -26,7 +26,7 @@
<a class="active item model_benchmark"
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a>
<a class="item aisafety_benchmark"
href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a>
href="{{.RepoLink}}/modelsafety/create_gpu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>
<div>
@@ -124,7 +124,7 @@
<a class="item model_benchmark"
href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a>
<a class="item aisafety_benchmark"
href="{{.RepoLink}}/modelsafety/create_gpu">模型安全评测</a>
href="{{.RepoLink}}/modelsafety/create_gpu">{{.i18n.Tr "modelsafety.model_security_evaluation"}}</a>
</div>
</div>



+ 3
- 0
templates/repo/cloudbrain/show.tmpl View File

@@ -111,7 +111,9 @@
<td class="ti-text-form-content">
<div class="text-span text-span-w" id="{{.VersionName}}-code">
{{.BranchName}}
{{if not .BootFile}}
<span style="margin-left:1rem" class="ui label">{{SubStr .CommitID 0 10}}</span>
{{end}}
</div>
</td>
</tr>
@@ -376,6 +378,7 @@
{{template "base/footer" .}}
<script src="{{StaticUrlPrefix}}/js/specsuse.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<script>
$('.menu .item').tab()
$(document).ready(function () {
$('.ui.accordion').accordion({ selector: { trigger: '.icon' } });


+ 5
- 5
templates/repo/home.tmpl View File

@@ -311,7 +311,7 @@
<div class="ui six wide tablet four wide computer column">
<div id="repo-desc" data-IsAdmin="{{.Permission.IsAdmin}}"
data-IsArchived="{{.Repository.IsArchived}}">
<h4 id="about-desc" class="ui header">简介</h4>
<h4 id="about-desc" class="ui header"></h4>
<input type="hidden" id="edit-alias" value="{{.Repository.Alias}}">
<p>
{{if .Repository.DescriptionHTML}}
@@ -363,15 +363,15 @@
<h4 class="ui header">
{{$lenCon := len .ContributorInfo}}
{{if lt $lenCon 25 }}
<strong>贡献者 ({{len .ContributorInfo}})</strong>
<strong>{{.i18n.Tr "home.contributors"}} ({{len .ContributorInfo}})</strong>
{{else}}
<strong>贡献者 ({{len .ContributorInfo}}+)</strong>
<strong>{{.i18n.Tr "home.contributors"}} ({{len .ContributorInfo}}+)</strong>
{{end}}

<div class="ui right">
<!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">全部 {{svg "octicon-chevron-right" 16}}</a> -->
<!-- <a class="membersmore text grey" href="{{.RepoLink}}/contributors">{{.i18n.Tr "repo.computing.all"}} {{svg "octicon-chevron-right" 16}}</a> -->
<a class="membersmore text grey"
href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部
href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">{{.i18n.Tr "repo.computing.all"}}
{{svg "octicon-chevron-right" 16}}</a>
</div>
</h4>


+ 2
- 1
templates/repo/modelarts/trainjob/para_manage.tmpl View File

@@ -107,6 +107,7 @@

<script>
// 删除时用户确认
var lang_canceled_operation = {{.i18n.Tr "repo.canceled_operation"}};
function assertDelete(obj) {
if (obj.style.color == "rgb(204, 204, 204)") {
return
@@ -124,7 +125,7 @@
},
onHidden: function() {
if (flag == false) {
$('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut();
$('.alert').html(lang_canceled_operation).removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut();
}
}
})


+ 9
- 4
templates/repo/modelmanage/convertshowinfo.tmpl View File

@@ -501,6 +501,11 @@ td, th {
let downlaodFlag = {{$.canDownload}}
let taskID = {{$.task.ID}}
let realJobName = {{$.task.ID}}
let lang_scrolled_logs_top = {{$.i18n.Tr "repo.scrolled_logs_top"}};
let lang_scrolled_logs_top_pls_retry = {{$.i18n.Tr "repo.scrolled_logs_top_pls_retry"}};
let lang_scrolled_logs_bottom = {{$.i18n.Tr "repo.scrolled_logs_bottom"}};
let lang_scrolled_logs_bottom_pls_retry = {{$.i18n.Tr "repo.scrolled_logs_bottom_pls_retry"}};

$(document).ready(function(){
let url = window.location.href;
let urlArr = url.split('/')
@@ -746,7 +751,7 @@ td, th {
let end_line = $(`#log_npu input[name=end_line]`).val()
$.get(`/api/v1/repos/${userName}/${repoPath}/modelmanage/${taskID}/modelartlog?version_name=V0001&base_line=${end_line}&lines=50&order=desc`, (data) => {
if (data.Lines == 0){
$(`#log_npu_header`).text('您已翻阅至日志底部')
$(`#log_npu_header`).text(lang_scrolled_logs_bottom)
$(`#log_npu_message`).css('display', 'block')
setTimeout(function(){
$(`#log_npu_message`).css('display', 'none')
@@ -769,7 +774,7 @@ td, th {
let start_line = $(`#log_npu input[name=start_line]`).val()
$.get(`/api/v1/repos/${userName}/${repoPath}/modelmanage/${taskID}/modelartlog?version_name=V0001&base_line=${start_line}&lines=50&order=asc`, (data) => {
if (data.Lines == 0){
$(`#log_npu_header`).text('您已翻阅至日志顶部')
$(`#log_npu_header`).text(lang_scrolled_logs_top)
$(`#log_npu_message`).css('display', 'block')
setTimeout(function(){
$(`#log_npu_message`).css('display', 'none')
@@ -812,7 +817,7 @@ td, th {
$(`#log_npu input[name=end_line]`).val(data.EndLine) //如果变动就改变所对应的值
$(`#log_npu input[name=start_line]`).val(data.StartLine)
$(`#log_npu`).prepend('<pre>' + data.Content)
$(`#log_npu_header`).text('您已翻阅至日志顶部')
$(`#log_npu_header`).text(lang_scrolled_logs_top)
$(`#log_npu_message`).css('display', 'block')
setTimeout(function(){
$(`#log_npu_message`).css('display', 'none')
@@ -832,7 +837,7 @@ td, th {
$(`#log_npu`).append('<pre>' + data.Content)
$.get(`/api/v1/repos/${userName}/${repoPath}/modelmanage/${taskID}/modelartlog?version_name=V0001&base_line=${data.EndLine}&lines=50&order=desc`, (data) => {
if (data.Lines == 0){
$(`#log_npu_header`).text('您已翻阅至日志底部')
$(`#log_npu_header`).text(lang_scrolled_logs_bottom)
$(`#log_npu_message`).css('display', 'block')
setTimeout(function(){
$(`#log_npu_message`).css('display', 'none')


+ 46
- 4
templates/user/auth/signin.tmpl View File

@@ -1,9 +1,51 @@
{{template "base/head" .}}
<style>
@media only screen and (max-width: 1200px) {
._container {
display:block !important;
}
._left-img-area {
display: none;
}
._right_content_area {
}
._right_content_area .segment {
margin-left: auto !important;
border-top-left-radius: .28571429rem !important;
border-bottom-left-radius: .28571429rem !important;
border-left: border: 1px solid rgba(34,36,38,.15) !important;
}
}
</style>
<script>
var ActivityTpl = {{ .ActivityTpl }};
</script>
<div class="user signin{{if .LinkAccountMode}} icon{{end}}">
{{template "user/auth/signin_navbar" .}}
<div class="ui container">
<div class="ui raised very padded text container segment">
{{template "user/auth/signin_inner" .}}
<div class="ui container" style="margin-top:60px;">
<div class="_container" style="display:flex;justify-content:center;">
<div class="_left-img-area" style="padding-right:0;flex:2">
<div style="width:450px;height:100%;float:right;border-radius:0.28571429rem;border-top-right-radius: 0;
border-bottom-right-radius: 0;border-right:none !important;overflow: hidden;
-webkit-box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);
box-shadow: 0 2px 4px 0rgba(34,36,38,.12),0 2px 10px 0rgba(34,36,38,.15);">
{{ if .ActivityTpl }}
{{ .ActivityTpl | Safe}}
{{ else }}
{{ template "user/auth/signin_up_img_default" .}}
{{ end }}
</div>
</div>
<div class="_right_content_area" style="padding-left:0;flex:3;">
<div class="ui raised very padded text container segment" style="margin-left:0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: none !important;
">
{{template "user/auth/signin_navbar" .}}
{{template "user/auth/signin_inner" .}}
</div>
</div>
</div>
</div>
</div>


+ 43
- 4
templates/user/auth/signin_cloud_brain.tmpl View File

@@ -1,9 +1,48 @@
{{template "base/head" .}}
<style>
@media only screen and (max-width: 1200px) {
._container {
display:block !important;
}
._left-img-area {
display: none;
}
._right_content_area {
}
._right_content_area .segment {
margin-left: auto !important;
border-top-left-radius: .28571429rem !important;
border-bottom-left-radius: .28571429rem !important;
border-left: border: 1px solid rgba(34,36,38,.15) !important;
}
}
</style>
<div class="user signin">
{{template "user/auth/signin_navbar" .}}
<div class="ui container">
<div class="ui raised very padded text container segment">
{{template "user/auth/signin_cloudbrain" .}}
<div class="ui container" style="margin-top:60px;">
<div class="_container" style="display:flex;justify-content:center;">
<div class="_left-img-area" style="padding-right:0;flex:2">
<div style="width:450px;height:100%;float:right;border-radius:0.28571429rem;border-top-right-radius: 0;
border-bottom-right-radius: 0;border-right:none !important;overflow: hidden;
-webkit-box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);
box-shadow: 0 2px 4px 0rgba(34,36,38,.12),0 2px 10px 0rgba(34,36,38,.15);">
{{ if .ActivityTpl }}
{{ .ActivityTpl | Safe}}
{{ else }}
{{ template "user/auth/signin_up_img_default" .}}
{{ end }}
</div>
</div>
<div class="_right_content_area" style="padding-left:0;flex:3;">
<div class="ui raised very padded text container segment" style="margin-left:0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: none !important;
">
{{template "user/auth/signin_navbar" .}}
{{template "user/auth/signin_cloudbrain" .}}
</div>
</div>
</div>
</div>
</div>


+ 1
- 1
templates/user/auth/signin_navbar.tmpl View File

@@ -1,5 +1,5 @@
{{if or .EnablePhone .EnableOpenIDSignIn .EnableSSPI .EnableCloudBrain}}
<div class="ui secondary pointing tabular top attached borderless menu new-menu navbar">
<div class="ui secondary pointing tabular top attached borderless menu new-menu navbar" style="margin-bottom:45px !important;background-color:transparent !important;">
{{if .EnablePhone }}
<a class="{{if .PageIsPhoneLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/phone">
{{.i18n.Tr "phone.mobile_login"}}


+ 97
- 59
templates/user/auth/signin_phone.tmpl View File

@@ -1,73 +1,111 @@
{{template "base/head" .}}
<style>
@media only screen and (max-width: 1200px) {
._container {
display:block !important;
}
._left-img-area {
display: none;
}
._right_content_area {
}
._right_content_area .segment {
margin-left: auto !important;
border-top-left-radius: .28571429rem !important;
border-bottom-left-radius: .28571429rem !important;
border-left: border: 1px solid rgba(34,36,38,.15) !important;
}
}
</style>
<div class="user signin">
{{template "user/auth/signin_navbar" .}}
<div class="ui container">
<div class="ui raised very padded text container segment">
<style>
.full.height{background-color: #F9F9F9;}
.ui.left:not(.action){ float:none;}
.ui.left{ float:none;}
.ui.secondary.pointing.menu{ border-bottom:none;}
</style>
{{template "base/alert" .}}
<div class="ui negative message" style="display:none;">
<p></p>
</div>
<div class="ui centered grid">
<div class="sixteen wide mobile ten wide tablet ten wide computer column">
<div class="ui bottom aligned two column grid">
<div class="column">
<h2 class="ui header">
{{if .LinkAccountMode}}
{{.i18n.Tr "auth.oauth_signin_title"}}
{{else}}
{{.i18n.Tr "auth.login_userpass"}}
{{end}}
</h2>
</div>
{{if .ShowRegistrationButton}}
<div class="ui right floated column">
<a href="{{AppSubUrl}}/user/sign_up">{{.i18n.Tr "auth.sign_up_now" | Str2html}}</a>
</div>
{{end}}
<div class="ui container" style="margin-top:60px;">
<div class="_container" style="display:flex;justify-content:center;">
<div class="_left-img-area" style="padding-right:0;flex:2">
<div style="width:450px;height:100%;float:right;border-radius:0.28571429rem;border-top-right-radius: 0;
border-bottom-right-radius: 0;border-right:none !important;overflow: hidden;
-webkit-box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);
box-shadow: 0 2px 4px 0rgba(34,36,38,.12),0 2px 10px 0rgba(34,36,38,.15);">
{{ if .ActivityTpl }}
{{ .ActivityTpl | Safe}}
{{ else }}
{{ template "user/auth/signin_up_img_default" .}}
{{ end }}
</div>
<div class="ui grid">
<div class="column">
<form class="ui form" action="/user/login/phone" method="post">
{{.CsrfTokenHtml}}

{{if .EnablePhone }}
<div class="use-type" usetype="1" autofocus="true">
{{template "user/auth/phone_verify" .}}
</div>
{{end}}

<div class="two fields inline">
<div class="field">
<div class="ui checkbox">
<label>{{.i18n.Tr "auth.remember_me"}}</label>
<input name="remember" type="checkbox">
</div>
<div class="_right_content_area" style="padding-left:0;flex:3;">
<div class="ui raised very padded text container segment" style="margin-left:0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: none !important;
">
<style>
.full.height{background-color: #F9F9F9;}
.ui.left:not(.action){ float:none;}
.ui.left{ float:none;}
.ui.secondary.pointing.menu{ border-bottom:none;}
</style>
{{template "user/auth/signin_navbar" .}}
{{template "base/alert" .}}
<div class="ui negative message" style="display:none;">
<p></p>
</div>
<div class="ui centered grid">
<div class="sixteen wide mobile ten wide tablet ten wide computer column">
<div class="ui bottom aligned two column grid">
<div class="column">
<h2 class="ui header">
{{if .LinkAccountMode}}
{{.i18n.Tr "auth.oauth_signin_title"}}
{{else}}
{{.i18n.Tr "auth.login_userpass"}}
{{end}}
</h2>
</div>
{{if .ShowRegistrationButton}}
<div class="ui right floated column">
<a href="{{AppSubUrl}}/user/sign_up">{{.i18n.Tr "auth.sign_up_now" | Str2html}}</a>
</div>
{{end}}
</div>
<div class="field" style="padding-right: 0; text-align: right;">
<a href="{{AppSubUrl}}/user/forgot_password?type=phone">{{.i18n.Tr "auth.forgot_password"}}</a>
</div>
</div>
<div class="ui grid">
<div class="column">
<form class="ui form" action="/user/login/phone" method="post">
{{.CsrfTokenHtml}}

{{if .EnablePhone }}
<div class="use-type" usetype="1" autofocus="true">
{{template "user/auth/phone_verify" .}}
</div>
{{end}}

<div class="ui hidden divider"></div>
<div class="two fields inline">
<div class="field">
<div class="ui checkbox">
<label>{{.i18n.Tr "auth.remember_me"}}</label>
<input name="remember" type="checkbox">
</div>
</div>
<div class="field" style="padding-right: 0; text-align: right;">
<a href="{{AppSubUrl}}/user/forgot_password?type=phone">{{.i18n.Tr "auth.forgot_password"}}</a>
</div>
</div>

<div class="center aligned field">
<button class="fluid large ui blue button">
{{.i18n.Tr "sign_in"}}
</button>
<div class="ui hidden divider"></div>

<div class="center aligned field">
<button class="fluid large ui blue button">
{{.i18n.Tr "sign_in"}}
</button>
</div>
</form>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>

</div>
</div>
</div>
</div>
{{template "base/footer" .}}

+ 45
- 0
templates/user/auth/signin_up_img_default.tmpl View File

@@ -0,0 +1,45 @@
<div style="width:100%;height:100%;
border-radius: 0.28571429rem;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
-webkit-box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);
box-shadow: 0 2px 4px 0rgba(34,36,38,.12),0 2px 10px 0rgba(34,36,38,.15);
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 40px;
background: url('/img/login_bg_default.png') center center no-repeat;
background-size: cover;
border-right:none !important;
">
<div style="margin: 14px 0;">
<span style="font-weight:500;font-size:28px;color:rgb(0, 122, 255);">{{.i18n.Tr "auth.openi_community_really_awesome"}}</span>
</div>
<div style="margin: 14px 0;">
<span style="font-weight:300;font-size:14px;color:rgb(140, 162, 170);">{{.i18n.Tr "home.page_description"}}</span>
</div>
<div style="margin: 14px 0;">
<div style="width:111px">
<a href="https://openi.pcl.ac.cn/zeizei/OpenI_Learning">
<div style="
width: 111px;
height: 40px;
font-size: 14px;
border-color: rgb(0, 122, 255);
border-width: 1px;
border-style: solid;
color: rgb(0, 122, 255);
display:flex;
align-items: center;
justify-content: center;
">
<svg xmlns="http://www.w3.org/2000/svg" style="margin-right:8px;margin-top:-2px;" class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 fPsHiw svg-icon-path-icon fill" viewBox="0 0 32 32" width="16" height="16"><defs data-reactroot=""></defs><g><path fill="rgb(0, 122, 255)" d="M2.667 5.324c0.005-0.729 0.594-1.318 1.322-1.324h24.022c0.731 0 1.323 0.593 1.323 1.324v21.352c-0.005 0.729-0.594 1.318-1.322 1.324h-24.022c-0.731-0.001-1.323-0.593-1.323-1.324v0-21.352zM14.667 6.667h-9.333v18.667h9.333v-18.667zM17.333 6.667v18.667h9.333v-18.667h-9.333zM18.667 9.333h6.667v2.667h-6.667v-2.667zM18.667 13.333h6.667v2.667h-6.667v-2.667z"></path></g></svg>
<span>{{.i18n.Tr "custom.Platform_Tutorial"}}</span>
</div>
</a>
</div>
</div>
</div>



+ 136
- 97
templates/user/auth/signup_inner.tmpl View File

@@ -1,112 +1,151 @@
<style>
.full.height{background-color: #F9F9F9;}
</style>

<div class="ui container very padded {{if .LinkAccountMode}} icon{{end}}" style=" padding-top: 5.0rem; padding-bottom: 3.0rem;">
<div class="ui raised very padded text container segment">
<div class="ui centered grid">
<div class="sixteen wide mobile ten wide tablet ten wide computer column">
<div class="ui bottom aligned two column grid">
<div class="column">
<h2 class="ui header">
{{if .LinkAccountMode}}
{{.i18n.Tr "auth.oauth_signup_title"}}
{{else}}
{{.i18n.Tr "sign_up"}}
{{end}}
</h2>
</div>
{{if not .LinkAccountMode}}
<div class="ui right floated column">
<a href="{{AppSubUrl}}/user/login">{{.i18n.Tr "auth.register_helper_msg"}}</a>
</div>
{{end}}
</div>
<div class="ui grid">
<div class="column">
<form class="ui form" action="{{.SignUpLink}}" method="post">
{{.CsrfTokenHtml}}
{{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister)}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" style="display:none;">
<p></p>
</div>
{{if .DisableRegistration}}
<p>{{.i18n.Tr "auth.disable_register_prompt"}}</p>
{{else}}
<div class="field invitation_tips" style="font-weight:400;font-size:14px;color:rgba(250,140,22,1);{{if not .invitationCode}}display:none;{{end}}">
<span>{{.i18n.Tr "your_friend"}} <span class="__invitation_code__">{{.invitationCode}}</span> {{.i18n.Tr "invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources"}}</span>
</div>
<div class="field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
<input id="user_name" name="user_name" value="{{.user_name}}" placeholder="{{.i18n.Tr "username"}}" autofocus required>
</div>
<div class="field {{if .Err_Email}}error{{end}}">
<input id="email" name="email" type="email" value="{{.email}}" placeholder="{{.i18n.Tr "email"}}" required>
</div>

{{if not .DisablePassword}}
<div class="field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
<input id="password" name="password" type="password" value="{{.password}}" placeholder="{{.i18n.Tr "password"}}" autocomplete="off" required>
</div>
<div class="field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
<input id="retype" name="retype" type="password" value="{{.retype}}" placeholder="{{.i18n.Tr "re_type"}}" autocomplete="off" required>
</div>
{{end}}
{{if and .EnableCaptcha (eq .CaptchaType "image")}}
<div class="field">
{{.Captcha.CreateHtml}}
</div>
<div class="field {{if .Err_Captcha}}error{{end}}">
<input id="captcha" name="captcha" value="{{.captcha}}" placeholder="{{.i18n.Tr "captcha"}}" autocomplete="off">
</div>
{{end}}
{{if and .EnableCaptcha (eq .CaptchaType "recaptcha")}}
<div class="field required">
<div class="g-recaptcha" data-sitekey="{{ .RecaptchaSitekey }}"></div>
</div>
<style>
@media only screen and (max-width: 1200px) {
._container {
display:block !important;
}
._left-img-area {
display: none;
}
._right_content_area {
}
._right_content_area .segment {
margin-left: auto !important;
border-top-left-radius: .28571429rem !important;
border-bottom-left-radius: .28571429rem !important;
border-left: border: 1px solid rgba(34,36,38,.15) !important;
}
}
</style>
<div class="ui container very padded {{if .LinkAccountMode}} icon{{end}}" style=" padding-top: 5.0rem; padding-bottom: 3.0rem;">
<div class="_container" style="display:flex;justify-content:center;">
<div class="_left-img-area" style="padding-right:0;flex:2">
<div style="width:450px;height:100%;float:right;border-radius:0.28571429rem;border-top-right-radius: 0;
border-bottom-right-radius: 0;border-right:none !important;overflow: hidden;
-webkit-box-shadow: 0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15);
box-shadow: 0 2px 4px 0rgba(34,36,38,.12),0 2px 10px 0rgba(34,36,38,.15);">
{{ if .ActivityTpl }}
{{ .ActivityTpl | Safe}}
{{ else }}
{{ template "user/auth/signin_up_img_default" .}}
{{ end }}
</div>
</div>
<div class="_right_content_area" style="padding-left:0;flex:3;">
<div class="ui raised very padded text container segment" style="margin-left:0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
border-left: none !important;
">
<div class="ui centered grid">
<div class="sixteen wide mobile ten wide tablet ten wide computer column">
<div class="ui bottom aligned two column grid">
<div class="column">
<h2 class="ui header">
{{if .LinkAccountMode}}
{{.i18n.Tr "auth.oauth_signup_title"}}
{{else}}
{{.i18n.Tr "sign_up"}}
{{end}}
{{if .EnablePhone }}
<div class="use-type" usetype="0">
{{template "user/auth/phone_verify" .}}
</h2>
</div>
{{if not .LinkAccountMode}}
<div class="ui right floated column">
<a href="{{AppSubUrl}}/user/login">{{.i18n.Tr "auth.register_helper_msg"}}</a>
</div>
{{end}}
</div>
<div class="ui grid">
<div class="column">
<form class="ui form" action="{{.SignUpLink}}" method="post">
{{.CsrfTokenHtml}}
{{if or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister)}}
{{template "base/alert" .}}
{{end}}
<div class="ui negative message" style="display:none;">
<p></p>
</div>
{{end}}
<div class="field">
<div style="display:flex;">
<div style="display:flex;align-items:center;">
<span>{{.i18n.Tr "recommender"}}</span>
{{if .DisableRegistration}}
<p>{{.i18n.Tr "auth.disable_register_prompt"}}</p>
{{else}}
<div class="field invitation_tips" style="font-weight:400;font-size:14px;color:rgba(250,140,22,1);{{if not .invitationCode}}display:none;{{end}}">
<span>{{.i18n.Tr "your_friend"}} <span class="__invitation_code__">{{.invitationCode}}</span> {{.i18n.Tr "invite_you_to_join_the_OpenI_AI_Collaboration_Platform_and_enjoy_abundant_free_computing_resources"}}</span>
</div>
<div class="field {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
<input id="user_name" name="user_name" value="{{.user_name}}" placeholder="{{.i18n.Tr "username"}}" autofocus required>
</div>
<div class="field {{if .Err_Email}}error{{end}}">
<input id="email" name="email" type="email" value="{{.email}}" placeholder="{{.i18n.Tr "email"}}" required>
</div>
<input style="flex:1;margin-left:12px;" id="invitation_code" name="invitation_code" value="{{.invitationCode}}" {{if .invitationCode}}readonly="true"{{end}} autocomplete="off" />
</div>
</div>

<div class="field">
<div class="ui checkbox">
<input name="agree" type="checkbox" tabindex="0" class="hidden" {{if .agree}}checked{{end}}><label>{{.i18n.Tr "use_and_privacy_agree" "/home/term" "/home/privacy" | Safe}}</label>
</div>
</div>
<div class="ui hidden divider"></div>
<div class="center aligned field">
<button class="fluid large ui blue button">
{{if .LinkAccountMode}}
{{.i18n.Tr "auth.oauth_signup_submit"}}
{{else}}
{{.i18n.Tr "auth.create_new_account"}}
{{if not .DisablePassword}}
<div class="field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
<input id="password" name="password" type="password" value="{{.password}}" placeholder="{{.i18n.Tr "password"}}" autocomplete="off" required>
</div>
<div class="field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
<input id="retype" name="retype" type="password" value="{{.retype}}" placeholder="{{.i18n.Tr "re_type"}}" autocomplete="off" required>
</div>
{{end}}
</button>
</div>
{{end}}
</form>
</div>
{{if and .EnableCaptcha (eq .CaptchaType "image")}}
<div class="field">
{{.Captcha.CreateHtml}}
</div>
<div class="field {{if .Err_Captcha}}error{{end}}">
<input id="captcha" name="captcha" value="{{.captcha}}" placeholder="{{.i18n.Tr "captcha"}}" autocomplete="off">
</div>
{{end}}
{{if and .EnableCaptcha (eq .CaptchaType "recaptcha")}}
<div class="field required">
<div class="g-recaptcha" data-sitekey="{{ .RecaptchaSitekey }}"></div>
</div>
{{end}}
{{if .EnablePhone }}
<div class="use-type" usetype="0">
{{template "user/auth/phone_verify" .}}
</div>
{{end}}
<div class="field">
<div style="display:flex;">
<div style="display:flex;align-items:center;">
<span>{{.i18n.Tr "recommender"}}</span>
</div>
<input style="flex:1;margin-left:12px;" id="invitation_code" name="invitation_code" value="{{.invitationCode}}" {{if .invitationCode}}readonly="true"{{end}} autocomplete="off" />
</div>
</div>

<div class="field">
<div class="ui checkbox">
<input name="agree" type="checkbox" tabindex="0" class="hidden" {{if .agree}}checked{{end}}><label>{{.i18n.Tr "use_and_privacy_agree" "/home/term" "/home/privacy" | Safe}}</label>
</div>
</div>
<div class="ui hidden divider"></div>
<div class="center aligned field">
<button class="fluid large ui blue button">
{{if .LinkAccountMode}}
{{.i18n.Tr "auth.oauth_signup_submit"}}
{{else}}
{{.i18n.Tr "auth.create_new_account"}}
{{end}}
</button>
</div>
{{end}}
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

<script>
; (function() {
var getUrlParams = function() {


+ 3
- 2
web_src/js/components/Contributors.vue View File

@@ -3,9 +3,9 @@
<div class="row git-user-content">
<h3 class="ui header">
<div class="ui breadcrumb">
<a class="section" :href="url_code">代码</a>
<a class="section" :href="url_code">{{$i18n['code']}}</a>
<div class="divider"> / </div>
<div class="active section" >贡献者&nbsp;({{totalNum}})</div>
<div class="active section" >{{$i18n['contributors']}}&nbsp;({{totalNum}})</div>
</div>
</h3>
<div class="ui horizontal relaxed list">
@@ -76,6 +76,7 @@ watch: {

},
created(){
this.$i18n = window.i18n;
const url = window.location.pathname;
this.url = url;
let strIndex = this.url.indexOf("contributors")


+ 8
- 7
web_src/js/components/EditAboutInfo.vue View File

@@ -1,13 +1,13 @@
<template>
<div>
<h4 id="about-desc" class="ui header desc-home">简介
<h4 id="about-desc" class="ui header desc-home">{{$i18n['introduction']}}
<a class="edit-icon" v-if="IsPermit" id ="editBtn" href="javascript:void(0)" @click="editClick" >
<i class="gray edit outline icon" style="margin-right: 0;"></i>
</a>
</h4>
<edit-dialog-cmpt
:vmContext="vmContext"
dialogTitle="编辑仓库信息"
:dialogTitle="$i18n['edit_repository_information']"
v-model="editDataDialog"
:deleteCallback="editDataFunc"
:deleteLoading ="editDataListLoading"
@@ -19,11 +19,11 @@
</div>
<div slot="content">
<el-form label-position="top" :model="info" :rules="rule" ref="ruleForm">
<el-form-item label="简介" prop="desc">
<el-input v-model="info.desc" type="textarea" placeholder="请输入内容" :autosize="{minRows:4,maxRows:6}" maxlength="255" show-word-limit></el-input>
<el-form-item :label="$i18n['introduction']" prop="desc">
<el-input v-model="info.desc" type="textarea" :placeholder="$i18n['please_enter_the_content']" :autosize="{minRows:4,maxRows:6}" maxlength="255" show-word-limit></el-input>
</el-form-item>
<el-form-item label="主页" prop="index_web" >
<el-input v-model="info.index_web" placeholder="主页(eg: https://openi.pcl.ac.cn)"></el-input>
<el-form-item :label="$i18n['homePage']" prop="index_web" >
<el-input v-model="info.index_web" :placeholder="`${$i18n['homePage']}(eg: https://openi.pcl.ac.cn)`"></el-input>
</el-form-item>
</el-form>
</div>
@@ -53,8 +53,8 @@ export default {
index_web: '',
repo_name_name: '',
alias:'',
IsPermit:false
},
IsPermit: false,
// rule1:[{min:3,max:5,message:'1',trigger:"blur"}],
rule: {
index_web: [
@@ -147,6 +147,7 @@ export default {
}
},
created() {
this.$i18n = window.i18n;
this.getIsSigned();
}



+ 6
- 6
web_src/js/components/EditTopics.vue View File

@@ -3,7 +3,7 @@
<div class="input-search">
<el-input v-model="input" clearable :autofocus="true" @input="changeValue" id="topics_input" @keyup.enter.native="postTopic" placeholder="搜索或创建标签">
<el-input v-model="input" clearable :autofocus="true" @input="changeValue" id="topics_input" @keyup.enter.native="postTopic" :placeholder="$i18n['searchOrCreateTopics']">

</el-input>
<div class="scrolling-menu">
@@ -14,7 +14,7 @@
<div class="text">{{arr.topic_name.toLowerCase()}} </div>
</div>
<div v-if="showInputValue" class="addition item-text" @click="postTopic">
点击或回车添加<b class="user-add-label-text">{{input.toLowerCase()}}</b>标签
{{$i18n['clickOrEnterToAdd']}}<b class="user-add-label-text">{{input.toLowerCase()}}</b>{{$i18n['topic']}}
</div>
<div v-if="showAddTopic" class="item-text" @click="addPostTopic">
<div class="icon-wrapper">
@@ -98,7 +98,7 @@ export default {
this.Post(data,topics)
this.$set(this.showInitTopic,item,false)
if(this.arrayTopics.length===0){
$('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
$('#repo-topics1').append(`<span class="no-description text-italic">${this.$i18n['noTopics']}</span>`)
}else{
$('#repo-topics1').children('span').remove()
}
@@ -264,7 +264,7 @@ export default {
if(this.arrayTopics.length===0){
$('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
$('#repo-topics1').append(`<span class="no-description text-italic">${this.$i18n['noTopics']}</span>`)
}else{
$('#repo-topics1').children('span').remove()
}
@@ -386,12 +386,12 @@ mounted() {
});
if(this.arrayTopics.length===0){
$('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>')
$('#repo-topics1').append(`<span class="no-description text-italic">${this.$i18n['noTopics']}</span>`)
}
this.changeValue()
} ,
created(){
this.$i18n = window.i18n;
this.initTopics();
this.input=''


+ 2
- 2
web_src/js/components/Model.vue View File

@@ -450,7 +450,7 @@ export default {
onHidden: function () {
if (flag == false) {
$(".alert")
.html("您已取消操作")
.html(_this.i18n['canceled_operation'])
.removeClass("alert-success")
.addClass("alert-danger")
.show()
@@ -458,7 +458,7 @@ export default {
.fadeOut();
} else {
$(".alert")
.html("删除成功")
.html(_this.i18n['successfully_deleted'])
.removeClass("alert-danger")
.addClass("alert-success")
.show()


+ 3
- 2
web_src/js/components/basic/editDialog.vue View File

@@ -15,8 +15,8 @@
<div slot="footer" class="dialog-footer">

<button class="ui button" @click="deleteDialog = false">{{"取消"}}</button>
<button class="ui green button" @click="deleteCallback.call(vmContext,deleteParam)">{{"确定"}}</button>
<button class="ui button" @click="deleteDialog = false">{{$i18n['cancel']}}</button>
<button class="ui green button" @click="deleteCallback.call(vmContext,deleteParam)">{{$i18n['confirm']}}</button>
<!-- <el-button size="small" style="font-size: 1rem;padding: .78571429em 1.5em .78571429em;border-radius: .28571429rem;" @click="deleteDialog = false">{{"取消"}}</el-button>
<el-button size="small" style="background-color: #21ba45;color: #fff;font-size: 1rem;padding: .78571429em 1.5em .78571429em;border-radius: .28571429rem;" @click="deleteCallback.call(vmContext,deleteParam)">{{"确定"}}</el-button> -->
</div>
@@ -71,6 +71,7 @@ export default {
},
},
created() {
this.$i18n = window.i18n;
this.deleteDialog = this.value;
}
};


+ 61
- 60
web_src/js/components/images/Images.vue View File

@@ -3,27 +3,27 @@
<div class="header-wrapper">
<div class="ui container">
<el-row class="image_text">
<h1>云脑镜像</h1>
<h1>{{$i18n['cloudeBrainMirror']['cloud_brain_mirror']}}</h1>
</el-row>
</div>
</div>
<div class="ui container" id="header">
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic">
<el-tab-pane :label="$i18n['cloudeBrainMirror']['public_mirror']" name="first" v-loading="loadingPublic">
<template v-if="tableDataPublic.length !== 0">
<el-row style="align-items: center; display: flex">
<el-col :span="12">
<div>
<el-checkbox v-model="checked">仅显示平台推荐</el-checkbox>
<el-checkbox v-model="checked">{{$i18n['cloudeBrainMirror']['platform_recommendations']}}</el-checkbox>
</div>
</el-col>
<el-col :span="4"
><div style="visibility: hidden">TODO</div></el-col
><div style="visibility: hidden"></div></el-col
>
<el-col :span="8">
<div>
<el-input
placeholder="搜镜像Tag/描述/标签..."
:placeholder="$i18n['cloudeBrainMirror']['placeholder']"
v-model="search"
class="input-with-select"
@keyup.enter.native="searchName()"
@@ -33,7 +33,7 @@
slot="append"
icon="el-icon-search"
@click="searchName()"
>搜索</el-button
>{{$i18n['cloudeBrainMirror']['search']}}</el-button
>
</el-input>
</div>
@@ -46,7 +46,7 @@
:header-cell-style="tableHeaderStyle"
>
<el-table-column
label="镜像Tag"
:label="$i18n['cloudeBrainMirror']['mirror_tag']"
min-width="19%"
align="left"
prop="tag"
@@ -65,7 +65,7 @@
</template>
</el-table-column>
<el-table-column
label="镜像描述"
:label="$i18n['cloudeBrainMirror']['mirror_description']"
min-width="28%"
align="left"
prop="description"
@@ -86,7 +86,7 @@
</el-table-column>
<el-table-column
prop="cloudbrainType"
label="可用集群"
:label="$i18n['cloudeBrainMirror']['available_clusters']"
min-width="10%"
align="center"
>
@@ -96,7 +96,7 @@
</el-table-column>
<el-table-column
prop="creator"
label="创建者"
:label="$i18n['cloudeBrainMirror']['creator']"
min-width="8%"
align="center"
>
@@ -121,7 +121,7 @@
</el-table-column>
<el-table-column
prop="updatedUnix"
label="创建时间"
:label="$i18n['cloudeBrainMirror']['creation_time']"
align="center"
min-width="14%"
>
@@ -129,7 +129,7 @@
{{ scope.row.updatedUnix | transformTimestamp }}
</template>
</el-table-column>
<el-table-column align="center" min-width="21%" label="操作">
<el-table-column align="center" min-width="21%" :label="$i18n['cloudeBrainMirror']['operation']">
<template slot-scope="scope">
<div
style="
@@ -171,7 +171,7 @@
<span
style="padding: 0 1rem; color: #0366d6; cursor: pointer"
@click="copyUrl(scope.row.place)"
>复制地址</span
>{{$i18n['cloudeBrainMirror']['copy_address']}}</span
>
</div>
</template>
@@ -199,16 +199,16 @@
<el-row style="align-items: center; display: flex">
<el-col :span="12">
<div>
<el-checkbox v-model="checked">仅显示平台推荐</el-checkbox>
<el-checkbox v-model="checked">{{$i18n['cloudeBrainMirror']['platform_recommendations']}}</el-checkbox>
</div>
</el-col>
<el-col :span="4"
><div style="visibility: hidden">TODO</div></el-col
><div style="visibility: hidden"></div></el-col
>
<el-col :span="8">
<div>
<el-input
placeholder="搜镜像Tag/描述/标签..."
:placeholder="$i18n['cloudeBrainMirror']['placeholder']"
v-model="search"
class="input-with-select"
@keyup.enter.native="searchName()"
@@ -218,7 +218,7 @@
slot="append"
icon="el-icon-search"
@click="searchName()"
>搜索</el-button
>{{$i18n['cloudeBrainMirror']['search']}}</el-button
>
</el-input>
</div>
@@ -227,7 +227,7 @@
<el-empty :image-size="200"></el-empty>
</template>
</el-tab-pane>
<el-tab-pane label="我的镜像" name="second" v-loading="loadingCustom">
<el-tab-pane :label="$i18n['cloudeBrainMirror']['my_mirror']" name="second" v-loading="loadingCustom">
<template v-if="tableDataCustom.length !== 0">
<el-row style="align-items: center; display: flex">
<el-col :span="12">
@@ -239,7 +239,7 @@
<el-col :span="8">
<div>
<el-input
placeholder="搜镜像Tag/描述/标签..."
:placeholder="$i18n['cloudeBrainMirror']['placeholder']"
v-model="search"
class="input-with-select"
@keyup.enter.native="searchName()"
@@ -249,7 +249,7 @@
slot="append"
icon="el-icon-search"
@click="searchName()"
>搜索</el-button
>{{$i18n['cloudeBrainMirror']['search']}}</el-button
>
</el-input>
</div>
@@ -262,7 +262,7 @@
:header-cell-style="tableHeaderStyle"
>
<el-table-column
label="镜像Tag"
:label="$i18n['cloudeBrainMirror']['mirror_tag']"
min-width="19%"
align="left"
prop="tag"
@@ -287,7 +287,7 @@
</template>
</el-table-column>
<el-table-column
label="镜像描述"
:label="$i18n['cloudeBrainMirror']['mirror_description']"
min-width="27%"
align="left"
prop="description"
@@ -308,7 +308,7 @@
</el-table-column>
<el-table-column
prop="cloudbrainType"
label="可用集群"
:label="$i18n['cloudeBrainMirror']['available_clusters']"
min-width="9%"
align="center"
>
@@ -318,7 +318,7 @@
</el-table-column>
<el-table-column
prop="isPrivate"
label="状态"
:label="$i18n['cloudeBrainMirror']['state']"
min-width="10%"
align="center"
>
@@ -333,14 +333,14 @@
<span
v-if="scope.row.isPrivate"
style="color: rgb(250, 140, 22)"
>私有</span
>{{$i18n['cloudeBrainMirror']['private']}}</span
>
<span v-else style="color: rgb(19, 194, 141)">公开</span>
<span v-else style="color: rgb(19, 194, 141)">{{$i18n['cloudeBrainMirror']['public']}}</span>
<el-tooltip
v-if="scope.row.status === 0"
class="item"
effect="dark"
content="镜像提交中..."
:content="$i18n['cloudeBrainMirror']['mirror_committed']"
placement="top"
>
<i class="CREATING" style="margin-left: 0.3rem"></i>
@@ -350,7 +350,7 @@
v-if="scope.row.status === 2"
class="item"
effect="dark"
content="检测提交镜像是否大小超过20G!"
:content="$i18n['cloudeBrainMirror']['check_exceeds_20g']"
placement="top"
>
<i class="FAILED" style="margin-left: 0.3rem"></i>
@@ -360,7 +360,7 @@
v-if="scope.row.status === 1"
class="item"
effect="dark"
content="镜像提交成功"
:content="$i18n['cloudeBrainMirror']['mirror_submitted']"
placement="top"
>
<i class="SUCCEEDED" style="margin-left: 0.3rem"></i>
@@ -370,7 +370,7 @@
</el-table-column>
<el-table-column
prop="updatedUnix"
label="创建时间"
:label="$i18n['cloudeBrainMirror']['creation_time']"
align="center"
min-width="14%"
>
@@ -378,7 +378,7 @@
{{ scope.row.updatedUnix | transformTimestamp }}
</template>
</el-table-column>
<el-table-column align="center" min-width="21%" label="操作">
<el-table-column align="center" min-width="21%" :label="$i18n['cloudeBrainMirror']['operation']">
<template slot-scope="scope">
<div
style="
@@ -412,24 +412,24 @@
<span
style="padding: 0 1rem; color: #0366d6; cursor: pointer"
@click="copyUrl(scope.row.place)"
>复制地址</span
>{{$i18n['cloudeBrainMirror']['copy_address']}}</span
>
<div style="padding-left: 1rem; cursor: pointer">
<el-dropdown size="medium">
<span class="el-dropdown-link">
更多<i
{{$i18n['cloudeBrainMirror']['more']}}<i
class="el-icon-arrow-down el-icon--right"
></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
@click.native="eidtImage(scope.row.id)"
>编辑</el-dropdown-item
>{{$i18n['cloudeBrainMirror']['edit']}}</el-dropdown-item
>
<el-dropdown-item
style="color: red"
@click.native="deleteImage(scope.row.id)"
>删除</el-dropdown-item
>{{$i18n['cloudeBrainMirror']['delete']}}</el-dropdown-item
>
</el-dropdown-menu>
</el-dropdown>
@@ -459,15 +459,15 @@
<template v-else>
<el-row style="align-items: center; display: flex">
<el-col :span="12">
<div style="visibility: hidden">TODO</div>
<div style="visibility: hidden"></div>
</el-col>
<el-col :span="4"
><div style="visibility: hidden">TODO</div></el-col
><div style="visibility: hidden"></div></el-col
>
<el-col :span="8">
<div>
<el-input
placeholder="搜镜像Tag/描述/标签..."
:placeholder="$i18n['cloudeBrainMirror']['placeholder']"
v-model="search"
class="input-with-select"
@keyup.enter.native="searchName()"
@@ -477,7 +477,7 @@
slot="append"
icon="el-icon-search"
@click="searchName()"
>搜索</el-button
>{{$i18n['cloudeBrainMirror']['search']}}</el-button
>
</el-input>
</div>
@@ -486,19 +486,19 @@
<el-empty :image-size="200"></el-empty>
</template>
</el-tab-pane>
<el-tab-pane label="我收藏的镜像" name="third">
<el-tab-pane :label="$i18n['cloudeBrainMirror']['my_favorite_mirror']" name="third">
<template v-if="tableDataStar.length !== 0">
<el-row style="align-items: center; display: flex">
<el-col :span="12">
<div style="visibility: hidden">TODO</div>
<div style="visibility: hidden"></div>
</el-col>
<el-col :span="4"
><div style="visibility: hidden">TODO</div></el-col
><div style="visibility: hidden"></div></el-col
>
<el-col :span="8">
<div>
<el-input
placeholder="搜镜像Tag/描述/标签..."
:placeholder="$i18n['cloudeBrainMirror']['placeholder']"
v-model="search"
class="input-with-select"
@keyup.enter.native="searchName()"
@@ -508,7 +508,7 @@
slot="append"
icon="el-icon-search"
@click="searchName()"
>搜索</el-button
>{{$i18n['cloudeBrainMirror']['search']}}</el-button
>
</el-input>
</div>
@@ -521,7 +521,7 @@
:header-cell-style="tableHeaderStyle"
>
<el-table-column
label="镜像Tag"
:label="$i18n['cloudeBrainMirror']['mirror_tag']"
min-width="19%"
align="left"
prop="tag"
@@ -540,7 +540,7 @@
</template>
</el-table-column>
<el-table-column
label="镜像描述"
:label="$i18n['cloudeBrainMirror']['mirror_description']"
min-width="28%"
align="left"
prop="description"
@@ -561,7 +561,7 @@
</el-table-column>
<el-table-column
prop="cloudbrainType"
label="可用集群"
:label="$i18n['cloudeBrainMirror']['available_clusters']"
min-width="10%"
align="center"
>
@@ -571,7 +571,7 @@
</el-table-column>
<el-table-column
prop="creator"
label="创建者"
:label="$i18n['cloudeBrainMirror']['creator']"
min-width="8%"
align="center"
>
@@ -596,7 +596,7 @@
</el-table-column>
<el-table-column
prop="updatedUnix"
label="创建时间"
:label="$i18n['cloudeBrainMirror']['creation_time']"
align="center"
min-width="14%"
>
@@ -604,7 +604,7 @@
{{ scope.row.updatedUnix | transformTimestamp }}
</template>
</el-table-column>
<el-table-column align="center" min-width="21%" label="操作">
<el-table-column align="center" min-width="21%" :label="$i18n['cloudeBrainMirror']['operation']">
<template slot-scope="scope">
<div
style="
@@ -639,7 +639,7 @@
<span
style="padding: 0 1rem; color: #0366d6; cursor: pointer"
@click="copyUrl(scope.row.place)"
>复制地址</span
>{{$i18n['cloudeBrainMirror']['copy_address']}}</span
>
</div>
</template>
@@ -667,15 +667,15 @@
<template v-else>
<el-row style="align-items: center; display: flex">
<el-col :span="12">
<div style="visibility: hidden">TODO</div>
<div style="visibility: hidden"></div>
</el-col>
<el-col :span="4"
><div style="visibility: hidden">TODO</div></el-col
><div style="visibility: hidden"></div></el-col
>
<el-col :span="8">
<div>
<el-input
placeholder="搜镜像Tag/描述/标签..."
:placeholder="$i18n['cloudeBrainMirror']['placeholder']"
v-model="search"
class="input-with-select"
@keyup.enter.native="searchName()"
@@ -685,7 +685,7 @@
slot="append"
icon="el-icon-search"
@click="searchName()"
>搜索</el-button
>{{$i18n['cloudeBrainMirror']['search']}}</el-button
>
</el-input>
</div>
@@ -859,7 +859,7 @@ export default {
onHidden: function () {
if (flag == false) {
$(".alert")
.html("您已取消操作")
.html(_this.$i18n['canceled_operation'])
.removeClass("alert-success")
.addClass("alert-danger")
.show()
@@ -867,7 +867,7 @@ export default {
.fadeOut();
} else {
$(".alert")
.html("删除成功")
.html(_this.$i18n['successfully_deleted'])
.removeClass("alert-danger")
.addClass("alert-success")
.show()
@@ -921,7 +921,7 @@ export default {
document.execCommand("Copy");
cInput.remove();
$("body").toast({
message: "复制成功!",
message: this.$i18n['cloudeBrainMirror']['copy_succeeded'],
showProgress: "bottom",
showIcon: "check circle",
class: "info",
@@ -954,9 +954,9 @@ export default {
},
transformPravite(val) {
if (val) {
return "私有";
return this.$i18n['cloudeBrainMirror']['private'];
} else {
return "公开";
return this.$i18n['cloudeBrainMirror']['public'];
}
},
transformTimestamp(timestamp) {
@@ -989,6 +989,7 @@ export default {
},
mounted() {},
created() {
this.$i18n = window.i18n;
const params = new URLSearchParams(location.search);
if (params.has("type") && params.get("type") == "myimage") {
this.activeName = "second";


+ 28
- 27
web_src/js/components/images/adminImages.vue View File

@@ -6,33 +6,33 @@
<div class="ui attached segment">
<div class="ui form ignore-dirty">
<div class="ui fluid action input">
<input type="text" placeholder="搜镜像Tag/描述/标签..." v-model="search"
<input type="text" :placeholder="$i18n['cloudeBrainMirror']['placeholder']" v-model="search"
@keyup.enter="searchName()">
<button class="ui blue button" @click="searchName()">搜索</button>
<button class="ui blue button" @click="searchName()">{{$i18n['cloudeBrainMirror']['search']}}</button>
</div>
</div>
</div>

<div class="ui ten wide column" style="margin: 1rem 0;">
<el-checkbox v-model="checked" style="padding: 0.5rem 1rem;">仅显示平台推荐</el-checkbox>
<el-checkbox v-model="checked" style="padding: 0.5rem 1rem;">{{$i18n['cloudeBrainMirror']['platform_recommendations']}}</el-checkbox>
<el-dropdown @command="handleCommand" trigger="click"
style="border: 1px solid rgba(34,36,38,.15);border-radius: 4px;padding: 0.5rem 1rem;">
<span class="el-dropdown-link">
{{dropdownPrivate}}<i class="el-icon-caret-bottom el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item :command="{label:'全部',private:''}">全部</el-dropdown-item>
<el-dropdown-item :command="{label:'公开',private:false}">公开</el-dropdown-item>
<el-dropdown-item :command="{label:'私有',private:true}">私有</el-dropdown-item>
<el-dropdown-item :command="{label:$i18n['all'],private:''}">{{$i18n['all']}}</el-dropdown-item>
<el-dropdown-item :command="{label:$i18n['cloudeBrainMirror']['public'],private:false}">{{$i18n['cloudeBrainMirror']['public']}}</el-dropdown-item>
<el-dropdown-item :command="{label:$i18n['cloudeBrainMirror']['private'],private:true}">{{$i18n['cloudeBrainMirror']['private']}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="ui six wide column right aligned" style="margin: 1rem 0;">
<a class="ui blue small button" href="/admin/images/commit_image">创建云脑镜像</a>
<a class="ui blue small button" href="/admin/images/commit_image">{{$i18n['cloudeBrainMirror']['create_cloud_brain_mirror']}}</a>
</div>
<div class="ui sixteen wide column" style="padding: 0;overflow-x: auto;">
<el-table :data="tableDataCustom" style="width: 100%;min-width:1700px;" :header-cell-style="tableHeaderStyle">
<el-table-column label="镜像Tag" min-width="19%" align="left" prop="tag">
<el-table-column :label="$i18n['cloudeBrainMirror']['mirror_tag']" min-width="19%" align="left" prop="tag">
<template slot-scope="scope">
<div style="display: flex;align-items: center;">
<a class="text-over image_title" :title="scope.row.tag">{{ scope.row.tag }}</a>
@@ -42,7 +42,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="镜像描述" min-width="28%" align="left" prop="description">
<el-table-column :label="$i18n['cloudeBrainMirror']['mirror_description']" min-width="28%" align="left" prop="description">
<template slot-scope="scope">
<div class="image_desc" :title="scope.row.description">{{ scope.row.description}}
</div>
@@ -53,18 +53,18 @@

</template>
</el-table-column>
<el-table-column prop="cloudbrainType" label="可用集群" min-width="10%" align="center">
<el-table-column prop="cloudbrainType" :label="$i18n['cloudeBrainMirror']['available_clusters']" min-width="10%" align="center">
<template slot-scope="scope">
{{scope.row.cloudbrainType | transformType}}
</template>
</el-table-column>
<el-table-column prop="isPrivate" label="状态" min-width="8%" align="center">
<el-table-column prop="isPrivate" :label="$i18n['cloudeBrainMirror']['state']" min-width="8%" align="center">
<template slot-scope="scope">
<span v-if="scope.row.isPrivate" style="color: rgb(250, 140, 22);">私有</span>
<span v-else style="color: rgb(19, 194, 141);">公开</span>
<span v-if="scope.row.isPrivate" style="color: rgb(250, 140, 22);">{{$i18n['cloudeBrainMirror']['private']}}</span>
<span v-else style="color: rgb(19, 194, 141);">{{$i18n['cloudeBrainMirror']['public']}}</span>
</template>
</el-table-column>
<el-table-column prop="creator" label="创建者" min-width="7%" align="center">
<el-table-column prop="creator" :label="$i18n['cloudeBrainMirror']['creator']" min-width="7%" align="center">
<template slot-scope="scope">
<a v-if="scope.row.userName||scope.row.relAvatarLink"
:href="'/' + scope.row.userName" :title="scope.row.userName">
@@ -75,12 +75,12 @@
</a>
</template>
</el-table-column>
<el-table-column prop="updatedUnix" label="创建时间" align="center" min-width="13%">
<el-table-column prop="updatedUnix" :label="$i18n['cloudeBrainMirror']['creation_time']" align="center" min-width="13%">
<template slot-scope="scope">
{{scope.row.updatedUnix | transformTimestamp}}
</template>
</el-table-column>
<el-table-column align="center" min-width="23%" label="操作">
<el-table-column align="center" min-width="23%" :label="$i18n['cloudeBrainMirror']['operation']">
<template slot-scope="scope">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div
@@ -95,22 +95,22 @@
</div>
<span style="padding: 0 1rem;color: rgb(250, 140, 22);cursor:pointer;"
v-if="scope.row.type==5"
@click="unSetRecommend(scope.$index,scope.row.id)">取消推荐</span>
@click="unSetRecommend(scope.$index,scope.row.id)">{{$i18n['cloudeBrainMirror']['cancel_recommendation']}}</span>
<span style="padding: 0 1rem;color: rgb(19, 194, 141);cursor:pointer;"
v-if="scope.row.type!==5 && !scope.row.isPrivate"
@click="setRecommend(scope.$index,scope.row.id)">设为推荐</span>
@click="setRecommend(scope.$index,scope.row.id)">{{$i18n['cloudeBrainMirror']['set_as_recommended']}}</span>
<span style="padding: 0 1rem;color:#0366d6;cursor:pointer;"
@click="copyUrl(scope.row.place)">复制地址</span>
@click="copyUrl(scope.row.place)">{{$i18n['cloudeBrainMirror']['copy_address']}}</span>
<div style="padding-left:1rem;cursor:pointer;">
<el-dropdown size="medium">
<span class="el-dropdown-link">
更多<i class="el-icon-arrow-down el-icon--right"></i>
{{$i18n['cloudeBrainMirror']['more']}}<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="eidtImage(scope.row.id)">编辑
<el-dropdown-item @click.native="eidtImage(scope.row.id)">{{$i18n['cloudeBrainMirror']['edit']}}
</el-dropdown-item>
<el-dropdown-item style="color: red;"
@click.native="deleteImage(scope.row.id)">删除</el-dropdown-item>
@click.native="deleteImage(scope.row.id)">{{$i18n['cloudeBrainMirror']['delete']}}</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
@@ -205,9 +205,9 @@
},
onHidden: function () {
if (flag == false) {
$('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut();
$('.alert').html(_this.$i18n['canceled_operation']).removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut();
} else {
$('.alert').html('删除成功').removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut();
$('.alert').html(_this.$i18n['successfully_deleted']).removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut();
}
}
})
@@ -269,9 +269,9 @@
},
transformPravite(val) {
if (val) {
return "私有"
return this.$i18n['cloudeBrainMirror']['private'];
} else {
return "公开"
return this.$i18n['cloudeBrainMirror']['public'];
}
},
transformTimestamp(timestamp) {
@@ -298,7 +298,8 @@
this.getImageListCustom()
},
created() {

this.$i18n = window.i18n;
this.dropdownPrivate = this.$i18n['all'];
}

};


+ 10
- 10
web_src/js/features/cloudbrainShow.js View File

@@ -54,10 +54,10 @@ export default async function initCloudrainSow() {
if (max) {
$("body").toast({
class: "black",
message: `您已翻阅至日志底部,请稍后再试!`,
message: i18n.scrolled_logs_bottom_pls_retry,
});
} else {
$(`.message${version_name} #header`).text("您已翻阅至日志底部");
$(`.message${version_name} #header`).text(i18n.scrolled_logs_bottom);
$(`.message${version_name}`).css("display", "block");
setTimeout(function () {
$(`.message${version_name}`).css("display", "none");
@@ -101,10 +101,10 @@ export default async function initCloudrainSow() {
if (max) {
$("body").toast({
class: "black",
message: `您已翻阅至日志顶部,请稍后再试!`,
message: i18n.scrolled_logs_top_pls_retry,
});
} else {
$(`.message${version_name} #header`).text("您已翻阅至日志顶部");
$(`.message${version_name} #header`).text(i18n.scrolled_logs_top);
$(`.message${version_name}`).css("display", "block");
setTimeout(function () {
$(`.message${version_name}`).css("display", "none");
@@ -181,10 +181,10 @@ export default async function initCloudrainSow() {
if (max) {
$("body").toast({
class: "black",
message: `您已翻阅至日志顶部,请稍后再试!`,
message: i18n.scrolled_logs_top_pls_retry,
});
} else {
$(`.message${version_name} #header`).text("您已翻阅至日志顶部");
$(`.message${version_name} #header`).text(i18n.scrolled_logs_top);
$(`.message${version_name}`).css("display", "block");
setTimeout(function () {
$(`.message${version_name}`).css("display", "none");
@@ -202,10 +202,10 @@ export default async function initCloudrainSow() {
if (max) {
$("body").toast({
class: "black",
message: `您已翻阅至日志顶部,请稍后再试!`,
message: i18n.scrolled_logs_top_pls_retry,
});
} else {
$(`.message${version_name} #header`).text("您已翻阅至日志顶部");
$(`.message${version_name} #header`).text(i18n.scrolled_logs_top);
$(`.message${version_name}`).css("display", "block");
setTimeout(function () {
$(`.message${version_name}`).css("display", "none");
@@ -299,10 +299,10 @@ export default async function initCloudrainSow() {
if (max) {
$("body").toast({
class: "black",
message: `您已翻阅至日志底部,请稍后再试!`,
message: i18n.scrolled_logs_bottom_pls_retry,
});
} else {
$(`.message${version_name} #header`).text("您已翻阅至日志底部");
$(`.message${version_name} #header`).text(i18n.scrolled_logs_bottom);
$(`.message${version_name}`).css("display", "block");
setTimeout(function () {
$(`.message${version_name}`).css("display", "none");


+ 1
- 1
web_src/js/features/cloudrbanin.js View File

@@ -267,7 +267,7 @@ export default async function initCloudrain() {
onHidden: function () {
if (flag == false) {
$(".alert")
.html("您已取消操作")
.html(i18n.canceled_operation)
.removeClass("alert-success")
.addClass("alert-danger")
.show()


+ 106
- 0
web_src/js/features/i18nVue.js View File

@@ -116,6 +116,59 @@ export const i18nVue = {
modify:"修改",
about:"约",
count:"个",
all:"全部",

introduction: '简介',
edit_repository_information: '编辑仓库信息',
please_enter_the_content: '请输入内容',
homePage: '主页',
cancel: '取消',
confirm: '确定',
contributors: '贡献者',
code: '代码',
searchOrCreateTopics: '搜索或创建标签',
clickOrEnterToAdd: '点击或回车添加',
topic: '标签',
topics: '标签',
noTopics: '暂无标签',
createTopicsTips: '标签名必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符',
canceled_operation: '您已取消操作',
successfully_deleted: '删除成功',

scrolled_logs_top: '您已翻阅至日志顶部',
scrolled_logs_top_pls_retry: '您已翻阅至日志顶部,请稍后再试!',
scrolled_logs_bottom: '您已翻阅至日志底部',
scrolled_logs_bottom_pls_retry: '您已翻阅至日志底部,请稍后再试!',

cloudeBrainMirror: {
cloud_brain_mirror: '云脑镜像',
public_mirror: '公开镜像',
platform_recommendations:'仅显示平台推荐',
placeholder: '搜镜像Tag/描述/标签...',
search:'搜索',
mirror_tag:'镜像Tag',
mirror_description:'镜像描述',
available_clusters: '可用集群',
creator: '创建者',
creation_time: '创建时间',
operation: '操作',
copy_address: '复制地址',
my_mirror: '我的镜像',
state: '状态',
private: '私有',
public: '公开',
mirror_committed: '镜像提交中...',
check_exceeds_20g:'检测提交镜像是否大小超过20G!',
mirror_submitted:'镜像提交成功',
edit: '编辑',
delete: '删除',
my_favorite_mirror: '我收藏的镜像',
more:'更多',
copy_succeeded: '复制成功!',
cancel_recommendation: '取消推荐',
set_as_recommended: '设为推荐',
create_cloud_brain_mirror: '创建云脑镜像',
},
},
US: {
computer_vision: "computer vision",
@@ -238,5 +291,58 @@ export const i18nVue = {
modify:"Modify",
about:"About",
count:"",
all:"All",

introduction: 'Introduction',
edit_repository_information: 'Edit repository information',
please_enter_the_content: 'Please enter the content',
homePage: 'Home page',
cancel: 'Cancel',
confirm: 'Confirm',
contributors: 'Contributors',
code: 'Code',
searchOrCreateTopics: 'Search or create topics',
clickOrEnterToAdd: 'Click or enter to add',
topic: 'Topic',
topics: 'Topics',
noTopics: 'No topics',
createTopicsTips: 'The topic name must start with Chinese, letters or numbers, can contain hyphens (-), and cannot exceed 35 characters in length',
canceled_operation: 'You have canceled the operation',
successfully_deleted: 'Successfully deleted',

scrolled_logs_top: 'You have scrolled to the top of the log',
scrolled_logs_top_pls_retry: 'You have scrolled to the top of the log, please try again later!',
scrolled_logs_bottom: 'You have scrolled to the bottom of the log',
scrolled_logs_bottom_pls_retry: 'You have scrolled to the bottom of the log, please try again later!',

cloudeBrainMirror: {
cloud_brain_mirror: 'Cloud Brain Mirror',
public_mirror: 'Public Mirror',
platform_recommendations:'Show platform recommendations only',
placeholder: 'Search Mirror tag / description / tag ... ',
search:'Search',
mirror_tag:'Mirror Tag',
mirror_description:'mirror_description ',
available_clusters: 'Available clusters',
creator: 'Creator',
creation_time: 'Creation time',
operation: 'Operation',
copy_address: 'Copy address',
my_mirror: 'My Mirror',
state: 'State',
private: 'Private',
public: 'Public',
mirror_committed: 'Mirror Committed...',
check_exceeds_20g:'Check whether the size of the submitted image exceeds 20g!',
mirror_submitted:'Image submitted successfully',
edit: 'Edit',
delete: 'Delete',
my_favorite_mirror: 'My Favorite Mirror',
more:'More',
copy_succeeded: 'Copy succeeded!',
cancel_recommendation: 'Cancel recommendation',
set_as_recommended: 'Set as recommended',
create_cloud_brain_mirror: 'Create cloud brain mirror',
},
},
};

+ 2
- 1
web_src/js/standalone/cloudbrainNew.js View File

@@ -398,7 +398,8 @@
html += `<option value="${data['child_types'][i].id}">${data['child_types'][i].value}</option>`;
}
}
document.getElementById("benchmark_child_types_id").innerHTML = html;
let el = document.getElementById("benchmark_child_types_id");
el && (el.innerHTML = html);
})
}
$(document).ready(function () {


+ 1
- 1
web_src/less/openi.less View File

@@ -1455,7 +1455,7 @@ i.SUCCEEDED {
white-space: nowrap;
}
.text-span-new {
width: 800px;
overflow: hidden;
text-overflow: ellipsis;
height: 20%;


+ 2
- 1
web_src/vuepages/pages/notebook/debug/index.vue View File

@@ -375,7 +375,7 @@ export default {
location.href=`${AppSubUrl}/authentication/wechat/bind`
}
if(err.response.status===401){
location.href=`${AppSubUrl}/user/login?redirect_to=${location.origin}${location.pathname}?type=login`
location.href=`${AppSubUrl}/user/login?redirect_to=${encodeURIComponent(location.origin+location.pathname + '?type=login&card='+ this.selectIndex)}`
return
}
this.btnStatus[index]=0
@@ -445,6 +445,7 @@ export default {
if(new URLSearchParams(window.location.search).get("type")==='login'){
that.getNotebookInfo()
that.dialogVisible = true;
that.selectIndex = Number(new URLSearchParams(window.location.search).get("card"))
}
document
.querySelector("#notebook-debug")


Loading…
Cancel
Save