Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/2143tags/v1.22.5.1
| @@ -0,0 +1,4 @@ | |||
| # Ignore artifacts: | |||
| dist | |||
| build | |||
| coverage | |||
| @@ -0,0 +1 @@ | |||
| {} | |||
| @@ -6,6 +6,7 @@ | |||
| package cmd | |||
| import ( | |||
| "code.gitea.io/gitea/services/repository" | |||
| "encoding/json" | |||
| "fmt" | |||
| "net/http" | |||
| @@ -208,6 +209,21 @@ func runServ(c *cli.Context) error { | |||
| os.Setenv(models.ProtectedBranchPRID, fmt.Sprintf("%d", 0)) | |||
| os.Setenv(models.EnvIsDeployKey, fmt.Sprintf("%t", results.IsDeployKey)) | |||
| os.Setenv(models.EnvKeyID, fmt.Sprintf("%d", results.KeyID)) | |||
| //set environment for pre-receive hook script | |||
| if verb == "git-receive-pack" { | |||
| os.Setenv(models.EnvRepoMaxFileSize, fmt.Sprint(setting.Repository.Upload.FileMaxSize)) | |||
| os.Setenv(models.EnvRepoMaxSize, fmt.Sprint(setting.Repository.RepoMaxSize)) | |||
| os.Setenv(models.EnvPushSizeCheckFlag, fmt.Sprint(setting.Repository.Upload.ShellFlag)) | |||
| if setting.Repository.Upload.ShellFlag == repository.SHELL_FLAG_ON { | |||
| env, _ := private.GetHookConfig(username, reponame) | |||
| if env != nil && len(env) > 0 { | |||
| repoSize := env[models.EnvRepoSize] | |||
| if repoSize != "" { | |||
| os.Setenv(models.EnvRepoSize, repoSize) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //LFS token authentication | |||
| if verb == lfsAuthenticateVerb { | |||
| @@ -160,6 +160,7 @@ type Cloudbrain struct { | |||
| User *User `xorm:"-"` | |||
| Repo *Repository `xorm:"-"` | |||
| BenchmarkType string `xorm:"-"` //算法评测,模型评测 | |||
| BenchmarkTypeName string `xorm:"-"` | |||
| BenchmarkTypeRankLink string `xorm:"-"` | |||
| StartTime timeutil.TimeStamp | |||
| @@ -1565,6 +1566,11 @@ func GetCloudbrainCountByUserID(userID int64, jobType string) (int, error) { | |||
| return int(count), err | |||
| } | |||
| func GetBenchmarkCountByUserID(userID int64) (int, error) { | |||
| count, err := x.In("status", JobWaiting, JobRunning).And("(job_type = ? or job_type = ? or job_type = ?) and user_id = ? and type = ?", string(JobTypeBenchmark), string(JobTypeBrainScore), string(JobTypeSnn4imagenet), userID, TypeCloudBrainOne).Count(new(Cloudbrain)) | |||
| return int(count), err | |||
| } | |||
| func GetCloudbrainNotebookCountByUserID(userID int64) (int, error) { | |||
| count, err := x.In("status", ModelArtsCreateQueue, ModelArtsCreating, ModelArtsStarting, ModelArtsReadyToStart, ModelArtsResizing, ModelArtsStartQueuing, ModelArtsRunning, ModelArtsRestarting). | |||
| And("job_type = ? and user_id = ? and type = ?", JobTypeDebug, userID, TypeCloudBrainTwo).Count(new(Cloudbrain)) | |||
| @@ -45,7 +45,7 @@ type ImageStar struct { | |||
| } | |||
| type ImageTopic struct { | |||
| ID int64 | |||
| ID int64 `xorm:"pk autoincr"` | |||
| Name string `xorm:"UNIQUE VARCHAR(105)"` | |||
| ImageCount int | |||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
| @@ -468,8 +468,13 @@ func (images ImageList) loadAttributes(e Engine, uid int64) error { | |||
| } | |||
| for i := range images { | |||
| images[i].UserName = users[images[i].UID].Name | |||
| images[i].RelAvatarLink = users[images[i].UID].RelAvatarLink() | |||
| if users[images[i].UID] != nil { | |||
| images[i].UserName = users[images[i].UID].Name | |||
| images[i].RelAvatarLink = users[images[i].UID].RelAvatarLink() | |||
| } else { | |||
| images[i].UserName = "" | |||
| images[i].RelAvatarLink = "" | |||
| } | |||
| if uid == -1 { | |||
| images[i].IsStar = false | |||
| } else { | |||
| @@ -523,17 +523,21 @@ DROP TRIGGER IF EXISTS es_udpate_repository_lang on public.language_stat; | |||
| CREATE OR REPLACE FUNCTION public.udpate_repository_lang() RETURNS trigger AS | |||
| $def$ | |||
| DECLARE | |||
| privateValue bigint; | |||
| BEGIN | |||
| if (TG_OP = 'UPDATE') then | |||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| select into privateValue updated_unix from public.repository where id=NEW.repo_id; | |||
| update public.repository_es SET updated_unix=privateValue,lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| elsif (TG_OP = 'INSERT') then | |||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| select into privateValue updated_unix from public.repository where id=NEW.repo_id; | |||
| update public.repository_es SET updated_unix=privateValue,lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id; | |||
| elsif (TG_OP = 'DELETE') then | |||
| if exists(select 1 from public.repository where id=OLD.repo_id) then | |||
| update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id; | |||
| end if; | |||
| end if; | |||
| return null; | |||
| return NEW; | |||
| END; | |||
| $def$ | |||
| LANGUAGE plpgsql; | |||
| @@ -1554,6 +1554,11 @@ func GetAllMirrorRepositoriesCount() (int64, error) { | |||
| return x.Where("is_mirror = ?", true).Count(repo) | |||
| } | |||
| func GetAllOrgRepositoriesCount() (int64, error) { | |||
| repo := new(Repository) | |||
| return x.Table("repository").Join("INNER", []string{"\"user\"", "u"}, "repository.owner_id = u.id and u.type=1").Count(repo) | |||
| } | |||
| func GetAllForkRepositoriesCount() (int64, error) { | |||
| repo := new(Repository) | |||
| return x.Where("is_fork = ?", true).Count(repo) | |||
| @@ -2,6 +2,8 @@ package models | |||
| import ( | |||
| "fmt" | |||
| "strconv" | |||
| "time" | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| ) | |||
| @@ -45,6 +47,7 @@ type SummaryStatistic struct { | |||
| NumRepoFork int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoMirror int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoSelf int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| NumRepoOrg int64 `xorm:"NOT NULL DEFAULT 0"` | |||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||
| UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` | |||
| } | |||
| @@ -69,6 +72,51 @@ func DeleteSummaryStatisticDaily(date string) error { | |||
| return nil | |||
| } | |||
| func GetLatest2SummaryStatistic() ([]*SummaryStatistic, error) { | |||
| summaryStatistics := make([]*SummaryStatistic, 0) | |||
| err := xStatistic.Desc("created_unix").Limit(2).Find(&summaryStatistics) | |||
| return summaryStatistics, err | |||
| } | |||
| func GetSummaryStatisticByTimeCount(beginTime time.Time, endTime time.Time) (int64, error) { | |||
| summaryStatistics := new(SummaryStatistic) | |||
| total, err := xStatistic.Asc("created_unix").Where("created_unix>=" + strconv.FormatInt(beginTime.Unix(), 10) + " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10)).Count(summaryStatistics) | |||
| return total, err | |||
| } | |||
| func GetSummaryStatisticByDateCount(dates []string) (int64, error) { | |||
| summaryStatistics := new(SummaryStatistic) | |||
| total, err := xStatistic.Asc("created_unix").In("date", dates).Count(summaryStatistics) | |||
| return total, err | |||
| } | |||
| func GetAllSummaryStatisticByTime(beginTime time.Time, endTime time.Time) ([]*SummaryStatistic, error) { | |||
| summaryStatistics := make([]*SummaryStatistic, 0) | |||
| err := xStatistic.Asc("created_unix").Where("created_unix>=" + strconv.FormatInt(beginTime.Unix(), 10) + " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10)).Find(&summaryStatistics) | |||
| return summaryStatistics, err | |||
| } | |||
| func GetSummaryStatisticByTime(beginTime time.Time, endTime time.Time, page int, pageSize int) ([]*SummaryStatistic, error) { | |||
| summaryStatistics := make([]*SummaryStatistic, 0) | |||
| err := xStatistic.Asc("created_unix").Limit(pageSize+1, (page-1)*pageSize).Where("created_unix>=" + strconv.FormatInt(beginTime.Unix(), 10) + " and created_unix<" + strconv.FormatInt(endTime.Unix(), 10)).Find(&summaryStatistics) | |||
| return summaryStatistics, err | |||
| } | |||
| func GetAllSummaryStatisticByDates(dates []string) ([]*SummaryStatistic, error) { | |||
| summaryStatistics := make([]*SummaryStatistic, 0) | |||
| err := xStatistic.Asc("created_unix").In("date", dates).Find(&summaryStatistics) | |||
| return summaryStatistics, err | |||
| } | |||
| func GetSummaryStatisticByDates(dates []string, page int, pageSize int) ([]*SummaryStatistic, error) { | |||
| summaryStatistics := make([]*SummaryStatistic, 0) | |||
| err := xStatistic.Asc("created_unix").In("date", dates).Limit(pageSize+1, (page-1)*pageSize).Find(&summaryStatistics) | |||
| return summaryStatistics, err | |||
| } | |||
| func InsertSummaryStatistic(summaryStatistic *SummaryStatistic) (int64, error) { | |||
| return xStatistic.Insert(summaryStatistic) | |||
| } | |||
| @@ -1,9 +1,11 @@ | |||
| package models | |||
| import ( | |||
| "encoding/json" | |||
| "fmt" | |||
| "sort" | |||
| "strconv" | |||
| "strings" | |||
| "time" | |||
| "code.gitea.io/gitea/modules/log" | |||
| @@ -227,7 +229,23 @@ func getLastCountDate() int64 { | |||
| return pageStartTime.Unix() | |||
| } | |||
| func QueryMetrics(start int64, end int64) ([]*UserMetrics, int64) { | |||
| func QueryMetricsPage(start int64, end int64) ([]*UserMetrics, int64) { | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| cond := "count_date >" + fmt.Sprint(start) + " and count_date<" + fmt.Sprint(end) | |||
| userMetricsList := make([]*UserMetrics, 0) | |||
| //.Limit(pageSize, page*pageSize) | |||
| if err := statictisSess.Table(new(UserMetrics)).Where(cond).OrderBy("count_date desc"). | |||
| Find(&userMetricsList); err != nil { | |||
| return nil, 0 | |||
| } | |||
| postUserMetricsList := postDeal(userMetricsList) | |||
| return postUserMetricsList, int64(len(postUserMetricsList)) | |||
| } | |||
| func QueryMetrics(start int64, end int64) ([]*UserMetrics, int) { | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| userMetricsList := make([]*UserMetrics, 0) | |||
| @@ -235,7 +253,91 @@ func QueryMetrics(start int64, end int64) ([]*UserMetrics, int64) { | |||
| Find(&userMetricsList); err != nil { | |||
| return nil, 0 | |||
| } | |||
| return userMetricsList, int64(len(userMetricsList)) | |||
| postUserMetricsList := postDeal(userMetricsList) | |||
| return postUserMetricsList, int(len(postUserMetricsList)) | |||
| } | |||
| func duplicateRemoval(userMetricsList []*UserMetrics) []*UserMetrics { | |||
| userMetricsResult := make([]*UserMetrics, 0) | |||
| for i := 0; i < len(userMetricsList); i++ { | |||
| if i > 0 { | |||
| if userMetricsList[i].DataDate == userMetricsList[i-1].DataDate { | |||
| continue | |||
| } | |||
| } | |||
| userMetricsResult = append(userMetricsResult, userMetricsList[i]) | |||
| } | |||
| return userMetricsResult | |||
| } | |||
| func postDeal(userMetricsList []*UserMetrics) []*UserMetrics { | |||
| duplicateRemovalUserMetricsList := duplicateRemoval(userMetricsList) | |||
| for _, userMetrics := range duplicateRemovalUserMetricsList { | |||
| userMetrics.DisplayDate = userMetrics.DataDate | |||
| userMetrics.TotalRegistUser = userMetrics.ActivateRegistUser + userMetrics.NotActivateRegistUser | |||
| userMetrics.TotalNotActivateRegistUser = userMetrics.TotalUser - userMetrics.TotalActivateRegistUser | |||
| } | |||
| return duplicateRemovalUserMetricsList | |||
| } | |||
| func QueryMetricsForAll(start int64, end int64) []*UserMetrics { | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| userMetricsList := make([]*UserMetrics, 0) | |||
| if err := statictisSess.Table(new(UserMetrics)).Where("count_date >" + fmt.Sprint(start) + " and count_date<" + fmt.Sprint(end)).OrderBy("count_date desc"). | |||
| Find(&userMetricsList); err != nil { | |||
| return nil | |||
| } | |||
| duplicateRemovalUserMetricsList := duplicateRemoval(userMetricsList) | |||
| return makeResultForMonth(duplicateRemovalUserMetricsList, len(duplicateRemovalUserMetricsList)) | |||
| } | |||
| func QueryMetricsForYear(start int64, end int64) []*UserMetrics { | |||
| allUserInfo, count := QueryMetrics(start, end) | |||
| return makeResultForMonth(allUserInfo, count) | |||
| } | |||
| func makeResultForMonth(allUserInfo []*UserMetrics, count int) []*UserMetrics { | |||
| monthMap := make(map[string]*UserMetrics) | |||
| if count > 0 { | |||
| for _, userMetrics := range allUserInfo { | |||
| dateTime := time.Unix(userMetrics.CountDate, 0) | |||
| month := fmt.Sprint(dateTime.Year()) + "-" + fmt.Sprint(int(dateTime.Month())) | |||
| if _, ok := monthMap[month]; !ok { | |||
| monthUserMetrics := &UserMetrics{ | |||
| DisplayDate: month, | |||
| ActivateRegistUser: userMetrics.ActivateRegistUser, | |||
| NotActivateRegistUser: userMetrics.NotActivateRegistUser, | |||
| TotalUser: userMetrics.TotalUser, | |||
| TotalNotActivateRegistUser: userMetrics.TotalUser - userMetrics.TotalActivateRegistUser, | |||
| TotalActivateRegistUser: userMetrics.TotalActivateRegistUser, | |||
| TotalHasActivityUser: userMetrics.TotalHasActivityUser, | |||
| HasActivityUser: userMetrics.HasActivityUser, | |||
| DaysForMonth: 1, | |||
| TotalRegistUser: userMetrics.ActivateRegistUser + userMetrics.NotActivateRegistUser, | |||
| } | |||
| monthMap[month] = monthUserMetrics | |||
| } else { | |||
| value := monthMap[month] | |||
| value.ActivateRegistUser += userMetrics.ActivateRegistUser | |||
| value.NotActivateRegistUser += userMetrics.NotActivateRegistUser | |||
| value.HasActivityUser += userMetrics.HasActivityUser | |||
| value.TotalRegistUser += userMetrics.ActivateRegistUser + userMetrics.NotActivateRegistUser | |||
| value.ActivateIndex = float64(value.ActivateRegistUser) / float64(value.TotalRegistUser) | |||
| value.DaysForMonth += 1 | |||
| } | |||
| } | |||
| } | |||
| result := make([]*UserMetrics, 0) | |||
| for _, value := range monthMap { | |||
| result = append(result, value) | |||
| } | |||
| sort.Slice(result, func(i, j int) bool { | |||
| return strings.Compare(result[i].DisplayDate, result[j].DisplayDate) > 0 | |||
| }) | |||
| return result | |||
| } | |||
| func QueryRankList(key string, tableName string, limit int) ([]*UserBusinessAnalysisAll, int64) { | |||
| @@ -540,6 +642,7 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||
| if minUserIndex > dateRecordAll.UserIndexPrimitive { | |||
| minUserIndex = dateRecordAll.UserIndexPrimitive | |||
| } | |||
| dateRecordBatch = append(dateRecordBatch, dateRecordAll) | |||
| if len(dateRecordBatch) >= BATCH_INSERT_SIZE { | |||
| insertTable(dateRecordBatch, tableName, statictisSess) | |||
| @@ -550,7 +653,9 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||
| dateRecordBatch = make([]UserBusinessAnalysisAll, 0) | |||
| } | |||
| if tableName == "user_business_analysis_all" { | |||
| if dateRecordAll.UserIndex > 0 || dateRecordAll.LoginCount > 0 { | |||
| tValue := getUserActivateAll(dateRecordAll) | |||
| if tValue > 0 { | |||
| log.Info("dateRecordAll name=" + dateRecordAll.Name + " value=" + fmt.Sprint(tValue)) | |||
| userMetrics["TotalHasActivityUser"] = getMapKeyStringValue("TotalHasActivityUser", userMetrics) + 1 | |||
| } | |||
| } | |||
| @@ -567,7 +672,9 @@ func refreshUserStaticTable(wikiCountMap map[string]int, tableName string, pageS | |||
| log.Info("insert all data failed." + err.Error()) | |||
| } | |||
| } | |||
| if tableName == "user_business_analysis_all" { | |||
| log.Info("TotalHasActivityUser=" + fmt.Sprint(userMetrics["TotalHasActivityUser"])) | |||
| } | |||
| //normalization | |||
| for k, v := range userIndexMap { | |||
| tmpResult := (v - minUserIndex) / (maxUserIndex - minUserIndex) | |||
| @@ -672,6 +779,8 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| log.Info("query commit code errr.") | |||
| } else { | |||
| log.Info("query commit code size, len=" + fmt.Sprint(len(CommitCodeSizeMap))) | |||
| CommitCodeSizeMapJson, _ := json.Marshal(CommitCodeSizeMap) | |||
| log.Info("CommitCodeSizeMapJson=" + string(CommitCodeSizeMapJson)) | |||
| } | |||
| CommitDatasetSizeMap, CommitDatasetNumMap := queryDatasetSize(start_unix, end_unix) | |||
| SolveIssueCountMap := querySolveIssue(start_unix, end_unix) | |||
| @@ -689,13 +798,13 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| statictisSess := xStatistic.NewSession() | |||
| defer statictisSess.Close() | |||
| cond := "type != 1 and is_active=true" | |||
| cond := "type != 1" | |||
| count, err := sess.Where(cond).Count(new(User)) | |||
| if err != nil { | |||
| log.Info("query user error. return.") | |||
| return err | |||
| } | |||
| userNewAddActivity := make(map[int64]map[int64]int64) | |||
| ParaWeight := getParaWeight() | |||
| userMetrics := make(map[string]int) | |||
| var indexTotal int64 | |||
| @@ -711,8 +820,6 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| log.Info("i=" + fmt.Sprint(i) + " userName=" + userRecord.Name) | |||
| dateRecord.CountDate = CountDate.Unix() | |||
| statictisSess.Delete(&dateRecord) | |||
| dateRecord.Email = userRecord.Email | |||
| dateRecord.RegistDate = userRecord.CreatedUnix | |||
| dateRecord.Name = userRecord.Name | |||
| @@ -767,6 +874,14 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| dateRecord.UserIndexPrimitive = getUserIndex(dateRecord, ParaWeight) | |||
| setUserMetrics(userMetrics, userRecord, start_unix, end_unix, dateRecord) | |||
| if getUserActivate(dateRecord) > 0 { | |||
| log.Info("has activity." + userRecord.Name) | |||
| addUserToMap(userNewAddActivity, userRecord.CreatedUnix, dateRecord.ID) | |||
| } | |||
| if userRecord.IsActive { | |||
| continue | |||
| } | |||
| statictisSess.Delete(&dateRecord) | |||
| _, err = statictisSess.Insert(&dateRecord) | |||
| if err != nil { | |||
| log.Info("insert daterecord failed." + err.Error()) | |||
| @@ -781,22 +896,75 @@ func CounDataByDateAndReCount(wikiCountMap map[string]int, startTime time.Time, | |||
| } | |||
| RefreshUserStaticAllTabel(wikiCountMap, userMetrics) | |||
| log.Info("start to update UserMetrics") | |||
| //insert userMetrics table | |||
| var useMetrics UserMetrics | |||
| useMetrics.CountDate = CountDate.Unix() | |||
| statictisSess.Delete(&useMetrics) | |||
| useMetrics.DataDate = DataDate | |||
| useMetrics.ActivateRegistUser = getMapKeyStringValue("ActivateRegistUser", userMetrics) | |||
| useMetrics.HasActivityUser = getMapKeyStringValue("HasActivityUser", userMetrics) | |||
| useMetrics.RegistActivityUser = 0 | |||
| useMetrics.NotActivateRegistUser = getMapKeyStringValue("NotActivateRegistUser", userMetrics) | |||
| useMetrics.TotalActivateRegistUser = getMapKeyStringValue("TotalActivateRegistUser", userMetrics) | |||
| useMetrics.TotalHasActivityUser = getMapKeyStringValue("TotalHasActivityUser", userMetrics) | |||
| statictisSess.Insert(&useMetrics) | |||
| count, err = sess.Where("type=0").Count(new(User)) | |||
| if err != nil { | |||
| log.Info("query user error. return.") | |||
| } | |||
| useMetrics.TotalUser = int(count) | |||
| if useMetrics.ActivateRegistUser+useMetrics.NotActivateRegistUser == 0 { | |||
| useMetrics.ActivateIndex = 0 | |||
| } else { | |||
| useMetrics.ActivateIndex = float64(useMetrics.ActivateRegistUser) / float64(useMetrics.ActivateRegistUser+useMetrics.NotActivateRegistUser) | |||
| } | |||
| statictisSess.Insert(&useMetrics) | |||
| //update new user activity | |||
| updateNewUserAcitivity(userNewAddActivity, statictisSess) | |||
| return nil | |||
| } | |||
| func updateNewUserAcitivity(currentUserActivity map[int64]map[int64]int64, statictisSess *xorm.Session) { | |||
| for key, value := range currentUserActivity { | |||
| useMetrics := &UserMetrics{CountDate: key} | |||
| has, err := statictisSess.Get(useMetrics) | |||
| if err == nil && has { | |||
| userIdArrays := strings.Split(useMetrics.HasActivityUserJson, ",") | |||
| for _, userIdStr := range userIdArrays { | |||
| userIdInt, err := strconv.ParseInt(userIdStr, 10, 64) | |||
| if err == nil { | |||
| value[userIdInt] = userIdInt | |||
| } | |||
| } | |||
| userIdArray := "" | |||
| for _, tmpValue := range value { | |||
| userIdArray += fmt.Sprint(tmpValue) + "," | |||
| } | |||
| useMetrics.HasActivityUser = len(value) | |||
| if len(userIdArray) > 0 { | |||
| useMetrics.HasActivityUserJson = userIdArray[0 : len(userIdArray)-1] | |||
| } | |||
| updateSql := "update public.user_metrics set has_activity_user_json='" + useMetrics.HasActivityUserJson + "',regist_activity_user=" + fmt.Sprint(useMetrics.HasActivityUser) + " where count_date=" + fmt.Sprint(key) | |||
| statictisSess.Exec(updateSql) | |||
| } | |||
| } | |||
| } | |||
| func addUserToMap(currentUserActivity map[int64]map[int64]int64, registDate timeutil.TimeStamp, userId int64) { | |||
| CountDateTime := time.Date(registDate.Year(), registDate.AsTime().Month(), registDate.AsTime().Day(), 0, 1, 0, 0, registDate.AsTime().Location()) | |||
| CountDate := CountDateTime.Unix() | |||
| if _, ok := currentUserActivity[CountDate]; !ok { | |||
| userIdMap := make(map[int64]int64, 0) | |||
| userIdMap[userId] = userId | |||
| currentUserActivity[CountDate] = userIdMap | |||
| } else { | |||
| currentUserActivity[CountDate][userId] = userId | |||
| } | |||
| } | |||
| func setUserMetrics(userMetrics map[string]int, user *User, start_time int64, end_time int64, dateRecord UserBusinessAnalysis) { | |||
| //ActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| //NotActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| @@ -875,6 +1043,27 @@ func getUserIndexFromAnalysisAll(dateRecord UserBusinessAnalysisAll, ParaWeight | |||
| return result | |||
| } | |||
| func getUserActivateAll(dateRecord UserBusinessAnalysisAll) int { | |||
| var result int | |||
| result += dateRecord.CodeMergeCount | |||
| result += dateRecord.CommitCount | |||
| result += dateRecord.IssueCount | |||
| result += dateRecord.CommentCount | |||
| result += dateRecord.FocusRepoCount | |||
| result += dateRecord.StarRepoCount | |||
| result += dateRecord.SolveIssueCount | |||
| result += dateRecord.EncyclopediasCount | |||
| result += dateRecord.CreateRepoCount | |||
| result += dateRecord.CloudBrainTaskNum | |||
| result += dateRecord.CommitModelCount | |||
| result += dateRecord.CommitDatasetNum | |||
| result += dateRecord.FocusOtherUser | |||
| result += dateRecord.CollectDataset | |||
| result += dateRecord.CollectImage | |||
| result += dateRecord.CommitCodeSize | |||
| return result | |||
| } | |||
| func getUserActivate(dateRecord UserBusinessAnalysis) int { | |||
| var result int | |||
| result += dateRecord.CodeMergeCount | |||
| @@ -400,10 +400,19 @@ type UserAnalysisPara struct { | |||
| } | |||
| type UserMetrics struct { | |||
| CountDate int64 `xorm:"pk"` | |||
| ActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| NotActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalHasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| CountDate int64 `xorm:"pk"` | |||
| ActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| NotActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| ActivateIndex float64 `xorm:"NOT NULL DEFAULT 0"` | |||
| RegistActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalRegistUser int `xorm:"-"` | |||
| TotalActivateRegistUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| TotalNotActivateRegistUser int `xorm:"-"` | |||
| TotalHasActivityUser int `xorm:"NOT NULL DEFAULT 0"` | |||
| DisplayDate string `xorm:"-"` | |||
| DataDate string `xorm:"NULL"` | |||
| DaysForMonth int `xorm:"NOT NULL DEFAULT 0"` | |||
| HasActivityUserJson string `xorm:"text NULL"` | |||
| } | |||
| @@ -740,3 +740,9 @@ type CreateCourseForm struct { | |||
| func (f *CreateCourseForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||
| return validate(errs, ctx.Data, f, ctx.Locale) | |||
| } | |||
| // RenameRepoFileForm form for renaming repository file | |||
| type RenameRepoFileForm struct { | |||
| TreePath string `binding:"Required;MaxSize(500)"` | |||
| LastCommit string | |||
| } | |||
| @@ -1,11 +1,12 @@ | |||
| package cloudbrain | |||
| import ( | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "encoding/json" | |||
| "errors" | |||
| "strconv" | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "code.gitea.io/gitea/modules/storage" | |||
| "code.gitea.io/gitea/models" | |||
| @@ -28,6 +29,8 @@ const ( | |||
| Snn4imagenetMountPath = "/snn4imagenet" | |||
| BrainScoreMountPath = "/brainscore" | |||
| TaskInfoName = "/taskInfo" | |||
| Snn4imagenetCommand = `/opt/conda/bin/python /snn4imagenet/testSNN_script.py --modelname '%s' --modelpath '/dataset' --modeldescription '%s'` | |||
| BrainScoreCommand = `bash /brainscore/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/dataset' -d '%s'` | |||
| SubTaskName = "task1" | |||
| @@ -184,7 +187,6 @@ func AdminOrImageCreaterRight(ctx *context.Context) { | |||
| } | |||
| func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, uuid, codePath, modelPath, benchmarkPath, snn4imagenetPath, brainScorePath, jobType, gpuQueue, description, branchName, bootFile, params string, benchmarkTypeID, benchmarkChildTypeID, resourceSpecId int) error { | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| @@ -347,7 +349,7 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||
| } | |||
| stringId := strconv.FormatInt(task.ID, 10) | |||
| if string(models.JobTypeBenchmark) == jobType { | |||
| if IsBenchmarkJob(jobType) { | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, stringId, displayJobName, models.ActionCreateBenchMarkTask) | |||
| } else if string(models.JobTypeTrain) == jobType { | |||
| notification.NotifyOtherTask(ctx.User, ctx.Repo.Repository, jobID, displayJobName, models.ActionCreateGPUTrainTask) | |||
| @@ -358,6 +360,10 @@ func GenerateTask(ctx *context.Context, displayJobName, jobName, image, command, | |||
| return nil | |||
| } | |||
| func IsBenchmarkJob(jobType string) bool { | |||
| return string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType | |||
| } | |||
| func RestartTask(ctx *context.Context, task *models.Cloudbrain, newID *string) error { | |||
| dataActualPath := setting.Attachment.Minio.RealPath + | |||
| setting.Attachment.Minio.Bucket + "/" + | |||
| @@ -4,7 +4,6 @@ import ( | |||
| "encoding/json" | |||
| "errors" | |||
| "fmt" | |||
| "math" | |||
| "net/http" | |||
| "strconv" | |||
| "strings" | |||
| @@ -213,8 +212,9 @@ func getQueryString(page int, size int, name string) string { | |||
| } | |||
| func CommitImage(jobID string, params models.CommitImageParams) error { | |||
| imageTag := strings.TrimSpace(params.ImageTag) | |||
| dbImage, err := models.GetImageByTag(params.ImageTag) | |||
| dbImage, err := models.GetImageByTag(imageTag) | |||
| if err != nil && !models.IsErrImageNotExist(err) { | |||
| return fmt.Errorf("resty CommitImage: %v", err) | |||
| @@ -224,12 +224,12 @@ func CommitImage(jobID string, params models.CommitImageParams) error { | |||
| if dbImage != nil { | |||
| if dbImage.UID != params.UID { | |||
| return models.ErrorImageTagExist{ | |||
| Tag: params.ImageTag, | |||
| Tag: imageTag, | |||
| } | |||
| } else { | |||
| if dbImage.Status == models.IMAGE_STATUS_COMMIT { | |||
| return models.ErrorImageCommitting{ | |||
| Tag: params.ImageTag, | |||
| Tag: imageTag, | |||
| } | |||
| } else { //覆盖提交 | |||
| @@ -282,9 +282,9 @@ sendjob: | |||
| CloudbrainType: params.CloudBrainType, | |||
| UID: params.UID, | |||
| IsPrivate: params.IsPrivate, | |||
| Tag: params.ImageTag, | |||
| Tag: imageTag, | |||
| Description: params.ImageDescription, | |||
| Place: setting.Cloudbrain.ImageURLPrefix + params.ImageTag, | |||
| Place: setting.Cloudbrain.ImageURLPrefix + imageTag, | |||
| Status: models.IMAGE_STATUS_COMMIT, | |||
| } | |||
| @@ -318,15 +318,15 @@ sendjob: | |||
| } | |||
| func CommitAdminImage(params models.CommitImageParams) error { | |||
| exist, err := models.IsImageExist(params.ImageTag) | |||
| imageTag := strings.TrimSpace(params.ImageTag) | |||
| exist, err := models.IsImageExist(imageTag) | |||
| if err != nil { | |||
| return fmt.Errorf("resty CommitImage: %v", err) | |||
| } | |||
| if exist { | |||
| return models.ErrorImageTagExist{ | |||
| Tag: params.ImageTag, | |||
| Tag: imageTag, | |||
| } | |||
| } | |||
| @@ -334,7 +334,7 @@ func CommitAdminImage(params models.CommitImageParams) error { | |||
| CloudbrainType: params.CloudBrainType, | |||
| UID: params.UID, | |||
| IsPrivate: params.IsPrivate, | |||
| Tag: params.ImageTag, | |||
| Tag: imageTag, | |||
| Description: params.ImageDescription, | |||
| Place: params.Place, | |||
| Status: models.IMAGE_STATUS_SUCCESS, | |||
| @@ -358,17 +358,16 @@ func CommitAdminImage(params models.CommitImageParams) error { | |||
| } | |||
| func updateImageStatus(image models.Image, isSetCreatedUnix bool, createTime time.Time) { | |||
| attemps := 5 | |||
| attemps := 60 | |||
| commitSuccess := false | |||
| time.Sleep(5 * time.Second) | |||
| for i := 0; i < attemps; i++ { | |||
| if commitSuccess { | |||
| break | |||
| } | |||
| for i := 0; i < attemps; i++ { | |||
| time.Sleep(20 * time.Second) | |||
| log.Info("the " + strconv.Itoa(i) + " times query cloudbrain images.Imagetag:" + image.Tag + "isSetCreate:" + strconv.FormatBool(isSetCreatedUnix)) | |||
| result, err := GetImagesPageable(1, pageSize, Custom, "") | |||
| if err == nil && result.Code == "S000" { | |||
| log.Info("images count:" + strconv.Itoa(result.Payload.Count)) | |||
| for _, v := range result.Payload.ImageInfo { | |||
| if v.Place == image.Place && (!isSetCreatedUnix || (isSetCreatedUnix && createTimeUpdated(v, createTime))) { | |||
| image.Status = models.IMAGE_STATUS_SUCCESS | |||
| @@ -380,10 +379,10 @@ func updateImageStatus(image models.Image, isSetCreatedUnix bool, createTime tim | |||
| } | |||
| } | |||
| //第一次循环等待4秒,第二次等待4的2次方16秒,...,第5次。。。 ,总共大概是20多分钟内进行5次重试 | |||
| var sleepTime = time.Duration(int(math.Pow(4, (float64(i + 1))))) | |||
| time.Sleep(sleepTime * time.Second) | |||
| if commitSuccess { | |||
| break | |||
| } | |||
| } | |||
| if !commitSuccess { | |||
| @@ -50,6 +50,11 @@ type HookPostReceiveBranchResult struct { | |||
| URL string | |||
| } | |||
| // HookEnvResult | |||
| type HookEnvResult struct { | |||
| Config map[string]string | |||
| } | |||
| // HookPreReceive check whether the provided commits are allowed | |||
| func HookPreReceive(ownerName, repoName string, opts HookOptions) (int, string) { | |||
| reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s", | |||
| @@ -122,3 +127,28 @@ func SetDefaultBranch(ownerName, repoName, branch string) error { | |||
| } | |||
| return nil | |||
| } | |||
| // GetHookConfig get hook config to set environment for hook script | |||
| func GetHookConfig(ownerName, repoName string) (map[string]string, string) { | |||
| reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/env/%s/%s", | |||
| url.PathEscape(ownerName), | |||
| url.PathEscape(repoName), | |||
| ) | |||
| req := newInternalRequest(reqURL, "GET") | |||
| req = req.Header("Content-Type", "application/json") | |||
| req.SetTimeout(60*time.Second, time.Duration(60)*time.Second) | |||
| resp, err := req.Response() | |||
| if err != nil { | |||
| return nil, fmt.Sprintf("Unable to contact gitea: %v", err.Error()) | |||
| } | |||
| defer resp.Body.Close() | |||
| if resp.StatusCode != http.StatusOK { | |||
| return nil, decodeJSONError(resp).Err | |||
| } | |||
| res := &HookEnvResult{} | |||
| _ = json.NewDecoder(resp.Body).Decode(res) | |||
| return res.Config, "" | |||
| } | |||
| @@ -109,6 +109,34 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro | |||
| return filelist, nil | |||
| } | |||
| // LsFilesStage list all files with stage format in index for the given paths | |||
| // if the given path is directory ,then return all files under it | |||
| // if the given path is file ,then return the file | |||
| func (t *TemporaryUploadRepository) LsFilesStage(paths ...string) ([]string, error) { | |||
| stdOut := new(bytes.Buffer) | |||
| stdErr := new(bytes.Buffer) | |||
| cmdArgs := []string{"ls-files", "-z", "-s", "--"} | |||
| for _, arg := range paths { | |||
| if arg != "" { | |||
| cmdArgs = append(cmdArgs, arg) | |||
| } | |||
| } | |||
| if err := git.NewCommand(cmdArgs...).RunInDirPipeline(t.basePath, stdOut, stdErr); err != nil { | |||
| log.Error("Unable to run git ls-files for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String()) | |||
| err = fmt.Errorf("Unable to run git ls-files for temporary repo of: %s Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String()) | |||
| return nil, err | |||
| } | |||
| filelist := make([]string, 0) | |||
| for _, line := range bytes.Split(stdOut.Bytes(), []byte{'\000'}) { | |||
| filelist = append(filelist, string(line)) | |||
| } | |||
| return filelist, nil | |||
| } | |||
| // RemoveFilesFromIndex removes the given files from the index | |||
| func (t *TemporaryUploadRepository) RemoveFilesFromIndex(filenames ...string) error { | |||
| stdOut := new(bytes.Buffer) | |||
| @@ -756,3 +756,210 @@ func createCommitRepoActions(repo *models.Repository, gitRepo *git.Repository, o | |||
| } | |||
| return actions, nil | |||
| } | |||
| // RenameRepoFileOptions | |||
| type RenameRepoFileOptions struct { | |||
| LastCommitID string | |||
| BranchName string | |||
| TreePath string | |||
| FromTreePath string | |||
| Message string | |||
| Author *IdentityOptions | |||
| Committer *IdentityOptions | |||
| } | |||
| // RenameRepoFile rename file in the given repository | |||
| func RenameRepoFile(repo *models.Repository, doer *models.User, opts *RenameRepoFileOptions) error { | |||
| // Branch must exist for this operation | |||
| if _, err := repo_module.GetBranch(repo, opts.BranchName); err != nil { | |||
| return err | |||
| } | |||
| //make sure user can commit to the given branch | |||
| if err := checkBranchProtection(doer, repo, opts.BranchName, opts.TreePath); err != nil { | |||
| return err | |||
| } | |||
| // Check that the path given in opts.treePath is valid (not a git path) | |||
| treePath := CleanUploadFileName(opts.TreePath) | |||
| if treePath == "" { | |||
| return models.ErrFilenameInvalid{ | |||
| Path: opts.TreePath, | |||
| } | |||
| } | |||
| // If there is a fromTreePath (we are copying it), also clean it up | |||
| fromTreePath := CleanUploadFileName(opts.FromTreePath) | |||
| if fromTreePath == "" && opts.FromTreePath != "" { | |||
| return models.ErrFilenameInvalid{ | |||
| Path: opts.FromTreePath, | |||
| } | |||
| } | |||
| author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer) | |||
| t, err := NewTemporaryUploadRepository(repo) | |||
| if err != nil { | |||
| log.Error("%v", err) | |||
| } | |||
| defer t.Close() | |||
| if err := t.Clone(opts.BranchName); err != nil { | |||
| return err | |||
| } | |||
| if err := t.SetDefaultIndex(); err != nil { | |||
| return err | |||
| } | |||
| // Get the commit of the original branch | |||
| commit, err := t.GetBranchCommit(opts.BranchName) | |||
| if err != nil { | |||
| return err // Couldn't get a commit for the branch | |||
| } | |||
| lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID) | |||
| if err != nil { | |||
| return fmt.Errorf("DeleteRepoFile: Invalid last commit ID: %v", err) | |||
| } | |||
| opts.LastCommitID = lastCommitID.String() | |||
| if opts.LastCommitID == "" { | |||
| // When updating a file, a lastCommitID needs to be given to make sure other commits | |||
| // haven't been made. We throw an error if one wasn't provided. | |||
| return models.ErrSHAOrCommitIDNotProvided{} | |||
| } | |||
| //if fromTreePath not exist,return error | |||
| _, err = commit.GetTreeEntryByPath(fromTreePath) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| // If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw | |||
| // an error. | |||
| if commit.ID.String() != opts.LastCommitID { | |||
| if changed, err := commit.FileChangedSinceCommit(fromTreePath, opts.LastCommitID); err != nil { | |||
| return err | |||
| } else if changed { | |||
| return models.ErrCommitIDDoesNotMatch{ | |||
| GivenCommitID: opts.LastCommitID, | |||
| CurrentCommitID: opts.LastCommitID, | |||
| } | |||
| } | |||
| } | |||
| //if treePath has been exist,return error | |||
| _, err = commit.GetTreeEntryByPath(treePath) | |||
| if err == nil || !git.IsErrNotExist(err) { | |||
| // Means the file has been exist in new path | |||
| return models.ErrFilePathInvalid{ | |||
| Message: fmt.Sprintf("a file exists where you’re trying to create a subdirectory [path: %s]", treePath), | |||
| Path: treePath, | |||
| Name: treePath, | |||
| Type: git.EntryModeBlob, | |||
| } | |||
| } | |||
| //move and add files to index | |||
| if err = moveAndAddFiles(fromTreePath, treePath, t); err != nil { | |||
| return err | |||
| } | |||
| // Now write the tree | |||
| treeHash, err := t.WriteTree() | |||
| if err != nil { | |||
| return err | |||
| } | |||
| // Now commit the tree | |||
| message := strings.TrimSpace(opts.Message) | |||
| commitHash, err := t.CommitTree(author, committer, treeHash, message) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| // Then push this tree to NewBranch | |||
| if err := t.Push(doer, commitHash, opts.BranchName); err != nil { | |||
| log.Error("%T %v", err, err) | |||
| return err | |||
| } | |||
| return nil | |||
| } | |||
| func checkBranchProtection(doer *models.User, repo *models.Repository, branchName, treePath string) error { | |||
| //make sure user can commit to the given branch | |||
| protectedBranch, err := repo.GetBranchProtection(branchName) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| if protectedBranch != nil { | |||
| if !protectedBranch.CanUserPush(doer.ID) { | |||
| return models.ErrUserCannotCommit{ | |||
| UserName: doer.LowerName, | |||
| } | |||
| } | |||
| if protectedBranch.RequireSignedCommits { | |||
| _, _, err := repo.SignCRUDAction(doer, repo.RepoPath(), branchName) | |||
| if err != nil { | |||
| if !models.IsErrWontSign(err) { | |||
| return err | |||
| } | |||
| return models.ErrUserCannotCommit{ | |||
| UserName: doer.LowerName, | |||
| } | |||
| } | |||
| } | |||
| patterns := protectedBranch.GetProtectedFilePatterns() | |||
| for _, pat := range patterns { | |||
| if pat.Match(strings.ToLower(treePath)) { | |||
| return models.ErrFilePathProtected{ | |||
| Path: treePath, | |||
| } | |||
| } | |||
| } | |||
| } | |||
| return nil | |||
| } | |||
| func moveAndAddFiles(oldTreePath, newTreePath string, t *TemporaryUploadRepository) error { | |||
| array, err := t.LsFilesStage(oldTreePath) | |||
| if err != nil { | |||
| return err | |||
| } | |||
| if len(array) == 0 { | |||
| return git.ErrNotExist{RelPath: oldTreePath} | |||
| } | |||
| stdOut := new(bytes.Buffer) | |||
| stdErr := new(bytes.Buffer) | |||
| stdIn := new(bytes.Buffer) | |||
| //write all files in stage format to the stdin, | |||
| //for each file,remove old tree path and add new tree path | |||
| //see the update-index help document at https://git-scm.com/docs/git-update-index | |||
| //especially see the content of "USING --INDEX-INFO" | |||
| for _, v := range array { | |||
| if v == "" { | |||
| continue | |||
| } | |||
| //example for v(mode SHA-1 stage file) | |||
| //100755 d294c88235ac05d3dece028d8a65590f28ec46ac 0 custom/conf/app.ini | |||
| v = strings.ReplaceAll(v, "0\t", "") | |||
| tmpArray := strings.Split(v, " ") | |||
| oldPath := tmpArray[2] | |||
| newPath := newTreePath + strings.TrimPrefix(oldPath, oldTreePath) | |||
| // mode 0 means remove file | |||
| stdIn.WriteString("0 0000000000000000000000000000000000000000\t") | |||
| stdIn.WriteString(oldPath) | |||
| stdIn.WriteByte('\000') | |||
| stdIn.WriteString(tmpArray[0] + " ") | |||
| stdIn.WriteString(tmpArray[1] + "\t") | |||
| stdIn.WriteString(newPath) | |||
| stdIn.WriteByte('\000') | |||
| } | |||
| if err := git.NewCommand("update-index", "--replace", "-z", "--index-info").RunInDirFullPipeline(t.basePath, stdOut, stdErr, stdIn); err != nil { | |||
| log.Error("Unable to update-index for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String()) | |||
| return fmt.Errorf("Unable to update-index for temporary repo: %s Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String()) | |||
| } | |||
| return nil | |||
| } | |||
| @@ -36,7 +36,7 @@ func getHookTemplates() (hookNames, hookTpls, giteaHookTpls, sizeLimitTpls []str | |||
| fmt.Sprintf("#!/usr/bin/env %s\n\"%s\" hook --config='%s' post-receive\n", setting.ScriptType, setting.AppPath, setting.CustomConf), | |||
| } | |||
| sizeLimitTpls = []string{ | |||
| fmt.Sprintf("#!/usr/bin/env %s\n\n\nset -o pipefail\n\nreadonly DEFAULT_FILE_MAXSIZE_MB=\"30\" \nreadonly CONFIG_NAME=\"hooks.maxfilesize\"\nreadonly NULLSHA=\"0000000000000000000000000000000000000000\"\nreadonly EXIT_SUCCESS=0\nreadonly EXIT_FAILURE=1\nreadonly DEFAULT_REPO_MAXSIZE_MB=\"1024\" \nreadonly CHECK_FLAG_ON=1\n\n\nstatus=\"$EXIT_SUCCESS\"\n\n# skip this hook entirely if shell check is not open\ncheck_flag=${PUSH_SIZE_CHECK_FLAG}\nif [[ $check_flag != $CHECK_FLAG_ON ]]; then\nexit $EXIT_SUCCESS\nfi\n\n\n#######################################\n# check the file max size limit\n#######################################\n\n# get maximum filesize (from repository-specific config)\nmaxsize_mb=\"${REPO_MAX_FILE_SIZE}\"\n\nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\necho \"failed to get ${CONFIG_NAME} from config\"\nexit \"$EXIT_FAILURE\"\nfi\n\npush_size=\"0\"\n# read lines from stdin (format: \"<oldref> <newref> <refname>\\n\")\nwhile read oldref newref refname; do\n# skip branch deletions\nif [[ \"$newref\" == \"$NULLSHA\" ]]; then\n continue\nfi\n\n# find large objects\n# check all objects from $oldref (possible $NULLSHA) to $newref, but\n# skip all objects that have already been accepted (i.e. are referenced by\n# another branch or tag).\n\nif [[ \"$oldref\" == \"$NULLSHA\" ]]; then\n target=\"$newref\"\nelse\n target=\"${oldref}..${newref}\"\nfi\nmaxsize=`expr $maxsize_mb \\* 1048576` \n\n# find objects in this push_size\n# print like:\n# 08da8e2ab9ae4095bf94dd71ac913132b880b463 commit 214\n# 43e993b768ede5740e8c65de2ed6edec25053ea1 tree 185\n# 4476971d76569039df7569af1b8d03c288f6b193 blob 20167318 b0417e6593a1.zip\nfiles=\"$(git rev-list --objects \"$target\" --tags=\\* | \\\n git cat-file $'--batch-check=%%(objectname) %%(objecttype) %%(objectsize) %%(rest)')\"\n \nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\n echo \"failed to check for large files in ref ${refname}\"\n continue\nfi\n\n# rewrite IFS to seperate line in $files\nIFS=$'\\n'\nfor file in $files; do\n # if don't unset IFS,temp_array=(${file}) will get error answer\n unset IFS\n temp_array=(${file})\n # add all commit files size\n push_size=`expr $push_size + ${temp_array[2]}`\n if [[ ${temp_array[2]} -gt $maxsize ]]; then\n\t if [[ \"$status\" == $EXIT_SUCCESS ]]; then\n\t\techo -e \"Error: Your push was rejected because it contains files larger than $(numfmt --to=iec \"$maxsize_mb\") Mb\"\n\t\techo \"oversize files:\"\n\t\tstatus=\"$EXIT_FAILURE\"\n\t fi\n\t echo -e \"\\033[31m- ${temp_array[3]} \\033[0m (ref: ${refname}) \"\n fi\ndone\n\nif [[ \"$status\" != $EXIT_SUCCESS ]]; then\n\texit \"$status\"\nfi\n\ndone\n\n#######################################\n# check the repo max size limit\n#######################################\nif [[ $push_size -eq \"0\" ]]; then\n\texit $EXIT_SUCCESS\nfi\n\n\nsizelimit_mb=\"${REPO_MAX_SIZE}\"\nlet sizelimit_b=$sizelimit_mb*1024*1024\n\n# repo size at here means the size of repo directory in server \nreposize_b=${REPO_CURRENT_SIZE}\n\ntotal=`expr $push_size + $reposize_b`\n\nif [ $total -gt $sizelimit_b ]; then\n echo \"Error: Your push was rejected because the repository size is large than $sizelimit_mb Mb\"\n exit $EXIT_FAILURE\nfi\n\n\nexit $EXIT_SUCCESS\n", setting.ScriptType, setting.CustomConf), | |||
| fmt.Sprintf("#!/usr/bin/env %s\n\n\nset -o pipefail\n\nreadonly DEFAULT_FILE_MAXSIZE_MB=\"30\" \nreadonly CONFIG_NAME=\"hooks.maxfilesize\"\nreadonly NULLSHA=\"0000000000000000000000000000000000000000\"\nreadonly EXIT_SUCCESS=0\nreadonly EXIT_FAILURE=1\nreadonly DEFAULT_REPO_MAXSIZE_MB=\"1024\" \nreadonly CHECK_FLAG_ON=1\n\n\nstatus=\"$EXIT_SUCCESS\"\n\n# skip this hook entirely if shell check is not open\ncheck_flag=${PUSH_SIZE_CHECK_FLAG}\nif [[ $check_flag != $CHECK_FLAG_ON ]]; then\nexit $EXIT_SUCCESS\nfi\n\n\n#######################################\n# check the file max size limit\n#######################################\n\n# get maximum filesize (from repository-specific config)\nmaxsize_mb=\"${REPO_MAX_FILE_SIZE}\"\n\nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\necho \"failed to get ${CONFIG_NAME} from config\"\nexit \"$EXIT_FAILURE\"\nfi\n\npush_size=\"0\"\n# read lines from stdin (format: \"<oldref> <newref> <refname>\\n\")\nwhile read oldref newref refname; do\n# skip branch deletions\nif [[ \"$newref\" == \"$NULLSHA\" ]]; then\n continue\nfi\n\n# find large objects\n# check all objects from $oldref (possible $NULLSHA) to $newref, but\n# skip all objects that have already been accepted (i.e. are referenced by\n# another branch or tag).\n\nnew_branch_flag=0\nif [[ \"$oldref\" == \"$NULLSHA\" ]]; then\n target=\"$newref\"\n new_branch_flag=1\n echo \"You are creating a new remote branch,openI will check all files in commit history to find oversize files\"\nelse\n target=\"${oldref}..${newref}\"\nfi\nmaxsize=`expr $maxsize_mb \\* 1048576` \n\n# find objects in this push_size\n# print like:\n# 08da8e2ab9ae4095bf94dd71ac913132b880b463 commit 214\n# 43e993b768ede5740e8c65de2ed6edec25053ea1 tree 185\n# 4476971d76569039df7569af1b8d03c288f6b193 blob 20167318 b0417e6593a1.zip\nfiles=\"$(git rev-list --objects \"$target\" | \\\n git cat-file $'--batch-check=%%(objectname) %%(objecttype) %%(objectsize) %%(rest)' | \\\n awk -F ' ' -v maxbytes=\"$maxsize\" 'BEGIN {totalIn=0} {if( $3 > maxbytes && $2 == \"blob\") { totalIn+=$3; print $4} else { totalIn+=$3}} END { printf (\"totalIn=\\t%%s\",totalIn)}' )\"\n \nif [[ \"$?\" != $EXIT_SUCCESS ]]; then\n echo \"failed to check for large files in ref ${refname}\"\n continue\nfi\n\nIFS=$'\\n'\n# rewrite IFS to seperate line in $files\nfor file in $files; do\n # if don't unset IFS,temp_array=(${file}) will get error answer\n \n if [[ ${file} == totalIn=* ]]; then\n\tIFS=$'\\t'\n\ttemp_array=(${file})\n\tpush_size=${temp_array[1]}\n\tcontinue\n fi\n\tunset IFS\n if [[ \"$status\" == $EXIT_SUCCESS ]]; then\n\t\techo -e \"Error: Your push was rejected because it contains files larger than $(numfmt --to=iec \"$maxsize_mb\") Mb\"\n\t\techo \"help document -- https://git.openi.org.cn/zeizei/OpenI_Learning/src/branch/master/docs/git/repository_capacity_help.md\"\n\t\techo \"oversize files:\"\n\t\tstatus=\"$EXIT_FAILURE\"\t\n fi\n echo -e \"\\033[31m- ${file}\\033[0m \"\ndone\n\nif [[ \"$status\" != $EXIT_SUCCESS ]]; then\n\texit \"$status\"\nfi\n\ndone\n\n#######################################\n# check the repo max size limit\n#######################################\nif [[ $push_size -eq \"0\" ]]; then\n\texit $EXIT_SUCCESS\nfi\n\n# if create new branch or tag,use count-objects -v to get pack size\nif [[ $new_branch_flag -eq 1 ]]; then\n size_kb=`git count-objects -v | grep 'size-pack' | sed 's/.*\\(size-pack:\\).//'`\n size_pack_kb=`git count-objects -v | grep 'size:' | sed 's/.*\\(size:\\).//'`\n\ttotal_kb=`expr $size_kb + $size_pack_kb`\n\tlet push_size=$total_kb*1024\nfi\n\nsizelimit_mb=\"${REPO_MAX_SIZE}\"\nlet sizelimit_b=$sizelimit_mb*1024*1024\n\n# repo size at here means the size of repo directory in server \nreposize_b=${REPO_CURRENT_SIZE}\n\ntotal=`expr $push_size + $reposize_b`\n\nif [ $total -gt $sizelimit_b ]; then\n echo \"Error: Your push was rejected because the repository size is large than $sizelimit_mb Mb\"\n echo \"see the help document--https://git.openi.org.cn/zeizei/OpenI_Learning/src/branch/master/docs/git/repository_capacity_help.md\"\n exit $EXIT_FAILURE\nfi\n\n\nexit $EXIT_SUCCESS", setting.ScriptType), | |||
| fmt.Sprintf(""), | |||
| fmt.Sprintf(""), | |||
| } | |||
| @@ -478,10 +478,11 @@ var ( | |||
| BenchmarkMaxDuration int64 | |||
| //snn4imagenet config | |||
| IsSnn4imagenetEnabled bool | |||
| Snn4imagenetOwner string | |||
| Snn4imagenetName string | |||
| Snn4imagenetServerHost string | |||
| IsSnn4imagenetEnabled bool | |||
| Snn4imagenetOwner string | |||
| Snn4imagenetName string | |||
| Snn4imagenetServerHost string | |||
| ModelBenchmarkMaxDuration int64 | |||
| //snn4imagenet config | |||
| IsBrainScoreEnabled bool | |||
| @@ -584,6 +585,7 @@ var ( | |||
| GrowthCommit float64 | |||
| GrowthComments float64 | |||
| RecordBeginTime string | |||
| GrowthBeginTime string | |||
| IgnoreMirrorRepo bool | |||
| }{} | |||
| @@ -1309,6 +1311,7 @@ func NewContext() { | |||
| Snn4imagenetOwner = sec.Key("OWNER").MustString("") | |||
| Snn4imagenetName = sec.Key("NAME").MustString("") | |||
| Snn4imagenetServerHost = sec.Key("HOST").MustString("") | |||
| ModelBenchmarkMaxDuration = sec.Key("MAX_DURATION").MustInt64(28800) | |||
| sec = Cfg.Section("brainscore") | |||
| IsBrainScoreEnabled = sec.Key("ENABLED").MustBool(false) | |||
| @@ -1415,7 +1418,8 @@ func SetRadarMapConfig() { | |||
| RadarMap.GrowthContributors = sec.Key("growth_contributors").MustFloat64(0.2) | |||
| RadarMap.GrowthCommit = sec.Key("growth_commit").MustFloat64(0.2) | |||
| RadarMap.GrowthComments = sec.Key("growth_comments").MustFloat64(0.2) | |||
| RadarMap.RecordBeginTime = sec.Key("record_beigin_time").MustString("2021-11-05") | |||
| RadarMap.RecordBeginTime = sec.Key("record_begin_time").MustString("2021-11-05") | |||
| RadarMap.GrowthBeginTime = sec.Key("growth_begin_time").MustString("2022-05-20") | |||
| RadarMap.IgnoreMirrorRepo = sec.Key("ignore_mirror_repo").MustBool(true) | |||
| } | |||
| @@ -5,6 +5,7 @@ | |||
| package ssh | |||
| import ( | |||
| "code.gitea.io/gitea/services/repository" | |||
| "crypto/rand" | |||
| "crypto/rsa" | |||
| "crypto/x509" | |||
| @@ -74,7 +75,7 @@ func sessionHandler(session ssh.Session) { | |||
| models.EnvPushSizeCheckFlag+"="+fmt.Sprint(setting.Repository.Upload.ShellFlag), | |||
| ) | |||
| if strings.HasPrefix(command, "git-receive-pack") { | |||
| if strings.HasPrefix(command, "git-receive-pack") && setting.Repository.Upload.ShellFlag == repository.SHELL_FLAG_ON { | |||
| repo := getRepoFromCommandStr(command) | |||
| if repo != nil { | |||
| cmd.Env = append(cmd.Env, models.EnvRepoSize+"="+fmt.Sprint(repo.Size)) | |||
| @@ -237,6 +237,8 @@ page_recommend_repo_desc=Excellent AI projects recommendation. To show your proj | |||
| page_recommend_repo_commit=Click here to submit. | |||
| page_recommend_repo_go=Click here to | |||
| page_recommend_repo_more=explore more projects. | |||
| page_recommend_activity=Community Activities | |||
| page_recommend_activity_desc=The community has prepared a wealth of activities, waiting for you to participate! | |||
| page_dev_env=Collaborative Development Environment | |||
| page_dev_env_desc=Provide a collaborative development environment for AI development, which is the biggest highlight that distinguishes the OpenI AI Collaboration Platform from other traditional Git platforms. | |||
| page_dev_env_desc_title=Unified Management of Development Elements | |||
| @@ -261,7 +263,7 @@ search_issue=Issue | |||
| search_pr=Pull Request | |||
| search_user=User | |||
| search_org=Organization | |||
| search_finded=Find | |||
| search_finded=Find | |||
| search_related=related | |||
| search_maybe=maybe | |||
| search_ge= | |||
| @@ -274,7 +276,7 @@ use_plt__fuction = To use the AI collaboration functions provided by this platfo | |||
| provide_resoure = Computing resources of CPU/GPU/NPU are provided freely for various types of AI tasks. | |||
| activity = Activity | |||
| no_events = There are no events related | |||
| or_t = or | |||
| or_t = or | |||
| [explore] | |||
| repos = Repositories | |||
| @@ -525,6 +527,19 @@ static.public.user_business_analysis_last30_day=Last_30_day | |||
| static.public.user_business_analysis_last_month=Last_Month | |||
| static.public.user_business_analysis_yesterday=Yesterday | |||
| static.public.user_business_analysis_all=All | |||
| metrics.sheetname=User Trend Analysis | |||
| metrics.date=Count Date | |||
| metrics.newregistuser=New registered user | |||
| metrics.newregistandactiveuser=New activated | |||
| metrics.hasactivateuser=New contributing activities | |||
| metrics.newregistnotactiveuser=New inactive | |||
| metrics.averageuser=Average new users | |||
| metrics.newuseractiveindex=Activation rate of new users | |||
| metrics.totalregistuser=Cumulative registered users | |||
| metrics.totalactiveduser=Cumulative activated users | |||
| metrics.totalhasactivityuser=Cumulative active users | |||
| [settings] | |||
| profile = Profile | |||
| account = Account | |||
| @@ -945,6 +960,15 @@ model_manager = Model | |||
| model_noright=No right | |||
| model_rename=Duplicate model name, please modify model name. | |||
| date=Date | |||
| repo_add=Project Increment | |||
| repo_total=Project Total | |||
| repo_public_add=Public Project Increment | |||
| repo_private_add=Private Project Increment | |||
| repo_fork_add=Fork Project Increment | |||
| repo_mirror_add=Mirror Project Increment | |||
| repo_self_add=Custom Project Increment | |||
| debug=Debug | |||
| debug_again=Restart | |||
| stop=Stop | |||
| @@ -1009,7 +1033,9 @@ get_repo_stat_error=Can not get the statistics of the repository. | |||
| get_repo_info_error=Can not get the information of the repository. | |||
| generate_statistic_file_error=Failed to generate file. | |||
| repo_stat_inspect=ProjectAnalysis | |||
| repo_stat_develop=ProjectTrendAnalysis | |||
| all=All | |||
| current_year=Current_Year | |||
| computing.all = All | |||
| computing.Introduction=Introduction | |||
| @@ -1090,12 +1116,18 @@ modelarts.train_job_para.connfirm=train_job_para.connfirm | |||
| modelarts.evaluate_job=Model Evaluation | |||
| modelarts.evaluate_job.new_job=New Model Evaluation | |||
| cloudbrain.benchmark.evaluate_type=Evaluation Type | |||
| cloudbrain.benchmark.evaluate_scenes = Evaluation Scenes | |||
| cloudbrain.benchmark.algorithm=Algorithm Evaluation | |||
| cloudbrain.benchmark.model=Model Evaluation | |||
| cloudbrain.benchmark.evaluate_child_type=Child Type | |||
| cloudbrain.benchmark.evaluate_mirror=Mirror | |||
| cloudbrain.benchmark.evaluate_train=Train Script | |||
| cloudbrain.benchmark.evaluate_test=Test Script | |||
| cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"Target detection","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"Target re-identification","second":[{"id":1,"value":"Vehicle re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"Image-based person re-identification","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"Multi-target tracking","second":[{"id":1,"value":"None","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]} | |||
| cloudbrain.morethanonejob=You already have a running or waiting task, create it after that task is over. | |||
| modelarts.infer_job_model = Model | |||
| modelarts.infer_job_model_file = Model File | |||
| @@ -1279,6 +1311,7 @@ editor.directory_is_a_file = Directory name '%s' is already used as a filename i | |||
| editor.file_is_a_symlink = '%s' is a symbolic link. Symbolic links cannot be edited in the web editor | |||
| editor.filename_is_a_directory = Filename '%s' is already used as a directory name in this repository. | |||
| editor.file_editing_no_longer_exists = The file being edited, '%s', no longer exists in this repository. | |||
| editor.file_or_directory_editing_no_longer_exists = The file or directory being edited, '%s', no longer exists in this repository. | |||
| editor.file_deleting_no_longer_exists = The file being deleted, '%s', no longer exists in this repository. | |||
| editor.file_changed_while_editing = The file contents have changed since you started editing. <a target="_blank" rel="noopener noreferrer" href="%s">Click here</a> to see them or <strong>Commit Changes again</strong> to overwrite them. | |||
| editor.file_already_exists = A file named '%s' already exists in this repository. | |||
| @@ -1299,6 +1332,8 @@ editor.require_signed_commit = Branch requires a signed commit | |||
| editor.repo_too_large = Repository can not exceed %d MB | |||
| editor.repo_file_invalid = Upload files are invalid | |||
| editor.upload_file_too_much = Can not upload more than %d files at a time | |||
| editor.rename = rename "%s" to %s" | |||
| editor.file_changed_while_renaming=The version of the file or folder to be renamed has changed. Please refresh the page and try again | |||
| commits.desc = Browse source code change history. | |||
| @@ -1363,7 +1398,7 @@ issues.add_milestone_at = `added this to the <b>%s</b> milestone %s` | |||
| issues.change_milestone_at = `modified the milestone from <b>%s</b> to <b>%s</b> %s` | |||
| issues.remove_milestone_at = `removed this from the <b>%s</b> milestone %s` | |||
| issues.add_branch_at=`added this to the <b>%s</b> branch %s` | |||
| issues.add_branch_at=`added this to the <b>%s</b> branch %s` | |||
| issues.add_tag_at =`added this to the <b>%s</b> tag %s` | |||
| issues.change_branch_tag_at= `modified the branch/tag from <b>%s</b> to <b>%s</b> %s` | |||
| issues.remove_branch_at=`removed this from the <b>%s</b> branch %s` | |||
| @@ -3011,8 +3046,9 @@ shared_memory = Shared Memory | |||
| DEBUG = DEBUG | |||
| SNN4IMAGENET = SNN4IMAGENET | |||
| BRAINSCORE = BRAINSCORE | |||
| SNN4IMAGENET = BENCHMARK | |||
| BRAINSCORE = BENCHMARK | |||
| TRAIN = TRAIN | |||
| INFERENCE = INFERENCE | |||
| BENCHMARK = BENCHMARK | |||
| BENCHMARK = BENCHMARK | |||
| brain_area = Brain Area | |||
| @@ -239,6 +239,8 @@ page_recommend_repo_desc=优秀的AI项目推荐;你的项目也想展示到 | |||
| page_recommend_repo_commit=点此提交 | |||
| page_recommend_repo_go=。进入 | |||
| page_recommend_repo_more=项目广场 | |||
| page_recommend_activity=社区活动 | |||
| page_recommend_activity_desc=社区准备了丰富的活动,等你来参加! | |||
| page_dev_env=协同开发环境 | |||
| page_dev_env_desc=启智AI协作开发平台与传统git平台最大的不同就在于提供了面向AI开发的协同开发环境 | |||
| page_dev_env_desc_title=开发要素统一管理 | |||
| @@ -269,7 +271,7 @@ search_maybe=约为 | |||
| search_ge=个 | |||
| wecome_AI_plt=欢迎来到启智AI协作平台! | |||
| explore_AI = 探索更好的AI,来这里发现更有意思的 | |||
| explore_AI = 探索更好的AI,来这里发现更有意思的 | |||
| datasets = 数据集 | |||
| repositories = 项目 | |||
| use_plt__fuction = 使用本平台提供的AI协作功能,如:托管代码、共享数据、调试算法或训练模型,请先 | |||
| @@ -277,7 +279,7 @@ provide_resoure = 平台目前免费提供CPU、GPU、NPU的算力资源,可 | |||
| create_pro = 创建项目 | |||
| activity = 活动 | |||
| no_events = 还没有与您相关的活动 | |||
| or_t = 或 | |||
| or_t = 或 | |||
| [explore] | |||
| @@ -530,6 +532,19 @@ static.public.user_business_analysis_last30_day=近30天 | |||
| static.public.user_business_analysis_last_month=上月 | |||
| static.public.user_business_analysis_yesterday=昨天 | |||
| static.public.user_business_analysis_all=所有 | |||
| metrics.sheetname=用户趋势分析 | |||
| metrics.date=日期 | |||
| metrics.newregistuser=新增注册用户 | |||
| metrics.newregistandactiveuser=新增已激活 | |||
| metrics.hasactivateuser=新增有贡献活动 | |||
| metrics.newregistnotactiveuser=新增未激活 | |||
| metrics.averageuser=平均新增用户 | |||
| metrics.newuseractiveindex=新增用户激活率 | |||
| metrics.totalregistuser=累计注册用户 | |||
| metrics.totalactiveduser=累计已激活 | |||
| metrics.totalhasactivityuser=累计有贡献活动 | |||
| [settings] | |||
| profile=个人信息 | |||
| account=账号 | |||
| @@ -946,6 +961,16 @@ model_manager = 模型 | |||
| model_noright=无权限操作 | |||
| model_rename=模型名称重复,请修改模型名称 | |||
| date=日期 | |||
| repo_add=新增项目 | |||
| repo_total=累计项目 | |||
| repo_public_add=新增公开项目 | |||
| repo_private_add=新增私有项目 | |||
| repo_fork_add=新增派生项目 | |||
| repo_mirror_add=新增镜像项目 | |||
| repo_self_add=新增自建项目 | |||
| debug=调试 | |||
| debug_again=再次调试 | |||
| stop=停止 | |||
| @@ -1017,7 +1042,9 @@ get_repo_stat_error=查询当前仓库的统计信息失败。 | |||
| get_repo_info_error=查询当前仓库信息失败。 | |||
| generate_statistic_file_error=生成文件失败。 | |||
| repo_stat_inspect=项目分析 | |||
| repo_stat_develop=项目趋势分析 | |||
| all=所有 | |||
| current_year=今年 | |||
| computing.all=全部 | |||
| computing.Introduction=简介 | |||
| @@ -1101,12 +1128,17 @@ modelarts.train_job_para.edit=编辑 | |||
| modelarts.train_job_para.connfirm=确定 | |||
| modelarts.evaluate_job=评测任务 | |||
| modelarts.evaluate_job.new_job=新建评测任务 | |||
| cloudbrain.benchmark.evaluate_scenes = 评测场景 | |||
| cloudbrain.benchmark.evaluate_type=评测类型 | |||
| cloudbrain.benchmark.algorithm=算法评测 | |||
| cloudbrain.benchmark.model=模型评测 | |||
| cloudbrain.benchmark.evaluate_child_type=子类型 | |||
| cloudbrain.benchmark.evaluate_mirror=镜像 | |||
| cloudbrain.benchmark.evaluate_train=训练程序 | |||
| cloudbrain.benchmark.evaluate_test=测试程序 | |||
| cloudbrain.benchmark.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]} | |||
| cloudbrain.benchmark.model.types={"type":[{"id":1,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=detection","first":"目标检测","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"yangzhx","repo_name":"detection_benchmark_script"}]},{"id":2,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=reid","first":"目标重识别","second":[{"id":1,"value":"车辆重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"},{"id":2,"value":"基于图像的行人重识别","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"JiahongXu","repo_name":"benchmark_reID_script"}]},{"id":3,"rank_link":"https://git.openi.org.cn/benchmark/?username=admin&algType=tracking","first":"多目标跟踪","second":[{"id":1,"value":"无","attachment":"84cf39c4-d8bc-41aa-aaa3-182ce289b105","owner":"lix07","repo_name":"MOT_benchmark_script"}]}]} | |||
| cloudbrain.morethanonejob=您已经创建了一个正在等待或运行中的同类任务,请等待任务结束再创建。 | |||
| modelarts.infer_job_model = 模型名称 | |||
| modelarts.infer_job_model_file = 模型文件 | |||
| @@ -1291,6 +1323,7 @@ editor.directory_is_a_file='%s' 已经作为文件名在此项目中存在。 | |||
| editor.file_is_a_symlink='%s' 是一个符号链接,无法在线编辑。 | |||
| editor.filename_is_a_directory='%s' 已经作为目录名在此项目中存在。 | |||
| editor.file_editing_no_longer_exists=正在编辑的文件 '%s' 已不存在。 | |||
| editor.file_or_directory_editing_no_longer_exists=正在编辑的文件或文件夹 '%s' 已不存在。 | |||
| editor.file_deleting_no_longer_exists=项目中不存在将被删除的文件‘%s’。 | |||
| editor.file_changed_while_editing=文件内容在您进行编辑时已经发生变动。<a target="_blank" rel="noopener noreferrer" href="%s">单击此处</a> 查看变动的具体内容,或者 <strong>再次提交</strong> 覆盖已发生的变动。 | |||
| editor.file_already_exists=此项目已经存在名为 '%s' 的文件。 | |||
| @@ -1311,6 +1344,8 @@ editor.require_signed_commit=分支需要签名提交 | |||
| editor.repo_too_large = 代码仓总大小不能超过%dMB | |||
| editor.repo_file_invalid = 提交的文件非法 | |||
| editor.upload_file_too_much = 不能同时提交超过%d个文件 | |||
| editor.rename = 重命名"%s"为"%s" | |||
| editor.file_changed_while_renaming=待重命名的文件或文件夹版本已发生变化,请您刷新页面后重试 | |||
| commits.desc=浏览代码修改历史 | |||
| commits.commits=次代码提交 | |||
| @@ -3021,9 +3056,10 @@ memory = 内存 | |||
| shared_memory = 共享内存 | |||
| DEBUG = 调试任务 | |||
| SNN4IMAGENET = 调试任务-脉冲神经网络图片分类测评 | |||
| BRAINSCORE = 调试任务-神经相似性测评 | |||
| SNN4IMAGENET = 评测任务 | |||
| BRAINSCORE = 评测任务 | |||
| TRAIN = 训练任务 | |||
| INFERENCE = 推理任务 | |||
| BENCHMARK = 评测任务 | |||
| brain_area = 脑区 | |||
| @@ -1123,6 +1123,12 @@ | |||
| "vue-template-es2015-compiler": "^1.9.0" | |||
| }, | |||
| "dependencies": { | |||
| "prettier": { | |||
| "version": "1.19.1", | |||
| "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", | |||
| "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", | |||
| "optional": true | |||
| }, | |||
| "source-map": { | |||
| "version": "0.6.1", | |||
| "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", | |||
| @@ -11003,10 +11009,10 @@ | |||
| "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" | |||
| }, | |||
| "prettier": { | |||
| "version": "1.19.1", | |||
| "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", | |||
| "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", | |||
| "optional": true | |||
| "version": "2.6.2", | |||
| "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", | |||
| "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", | |||
| "dev": true | |||
| }, | |||
| "pretty-error": { | |||
| "version": "2.1.1", | |||
| @@ -68,6 +68,7 @@ | |||
| "eslint-config-airbnb-base": "14.1.0", | |||
| "eslint-plugin-import": "2.20.2", | |||
| "eslint-plugin-vue": "6.2.2", | |||
| "prettier": "2.6.2", | |||
| "script-loader": "0.7.2", | |||
| "stylelint": "13.3.3", | |||
| "stylelint-config-standard": "20.0.0", | |||
| @@ -78,4 +79,4 @@ | |||
| "browserslist": [ | |||
| "defaults" | |||
| ] | |||
| } | |||
| } | |||
| @@ -6,6 +6,7 @@ if(isEmpty(token)){ | |||
| token = meta.attr("content"); | |||
| } | |||
| } | |||
| var swiperNewMessage = new Swiper(".newslist", { | |||
| direction: "vertical", | |||
| slidesPerView: 10, | |||
| @@ -15,6 +16,18 @@ var swiperNewMessage = new Swiper(".newslist", { | |||
| disableOnInteraction: false, | |||
| }, | |||
| }); | |||
| var swiperEvent = new Swiper(".event-list", { | |||
| slidesPerView: 2, | |||
| spaceBetween: 30, | |||
| pagination: { | |||
| el: ".swiper-pagination", | |||
| clickable: true, | |||
| }, | |||
| autoplay: { | |||
| delay: 2500, | |||
| disableOnInteraction: false, | |||
| }, | |||
| }); | |||
| var swiperRepo = new Swiper(".homepro-list", { | |||
| slidesPerView: 1, | |||
| slidesPerColumn: 2, | |||
| @@ -433,6 +446,38 @@ function queryRecommendData(){ | |||
| } | |||
| }); | |||
| $.ajax({ | |||
| type:"GET", | |||
| url:"/recommend/imageinfo", | |||
| headers: { | |||
| authorization:token, | |||
| }, | |||
| dataType:"json", | |||
| async:false, | |||
| success:function(json){ | |||
| displayActivity(json); | |||
| }, | |||
| error:function(response) { | |||
| } | |||
| }); | |||
| } | |||
| function displayActivity(json){ | |||
| var activityDiv = document.getElementById("recommendactivity"); | |||
| var html = ""; | |||
| if (json != null && json.length > 0){ | |||
| for(var i = 0; i < json.length;i++){ | |||
| var record = json[i] | |||
| html += "<div class=\"swiper-slide\">"; | |||
| html += "<a href=\"" + record["image_link"] + "\" class=\"ui fluid card\">"; | |||
| html += " <div class=\"image\"><img src=\"" + record["url"] + "\"></div>" | |||
| html += "</a>"; | |||
| html += "</div>"; | |||
| } | |||
| } | |||
| activityDiv.innerHTML = html; | |||
| swiperEvent.updateSlides(); | |||
| swiperEvent.updateProgress(); | |||
| } | |||
| function displayRepo(json){ | |||
| @@ -52,8 +52,8 @@ func CloudBrains(ctx *context.Context) { | |||
| var jobTypes []string | |||
| jobTypeNot := false | |||
| if jobType == string(models.JobTypeDebug) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeSnn4imagenet), string(models.JobTypeBrainScore), string(models.JobTypeDebug)) | |||
| if jobType == string(models.JobTypeBenchmark) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| } else if jobType != "all" && jobType != "" { | |||
| jobTypes = append(jobTypes, jobType) | |||
| } | |||
| @@ -535,6 +535,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/restoreFork", repo.RestoreForkNumber) | |||
| m.Get("/downloadAll", repo.ServeAllProjectsPeriodStatisticsFile) | |||
| m.Get("/downloadAllOpenI", repo.ServeAllProjectsOpenIStatisticsFile) | |||
| m.Get("/summary", repo.GetLatestProjectsSummaryData) | |||
| m.Get("/summary/period", repo.GetProjectsSummaryData) | |||
| m.Get("/summary/download", repo.GetProjectsSummaryDataFile) | |||
| m.Group("/project", func() { | |||
| m.Get("", repo.GetAllProjectsPeriodStatistics) | |||
| m.Get("/numVisit", repo.ProjectNumVisit) | |||
| @@ -547,7 +550,15 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| }) | |||
| }, operationReq) | |||
| m.Get("/query_user_metrics", operationReq, repo_ext.QueryMetrics) | |||
| m.Get("/query_metrics_current_month", operationReq, repo_ext.QueryUserMetricsCurrentMonth) | |||
| m.Get("/query_metrics_current_week", operationReq, repo_ext.QueryUserMetricsCurrentWeek) | |||
| m.Get("/query_metrics_current_year", operationReq, repo_ext.QueryUserMetricsCurrentYear) | |||
| m.Get("/query_metrics_last30_day", operationReq, repo_ext.QueryUserMetricsLast30Day) | |||
| m.Get("/query_metrics_last_month", operationReq, repo_ext.QueryUserMetricsLastMonth) | |||
| m.Get("/query_metrics_yesterday", operationReq, repo_ext.QueryUserMetricsYesterday) | |||
| m.Get("/query_metrics_all", operationReq, repo_ext.QueryUserMetricsAll) | |||
| m.Get("/query_user_metrics_page", operationReq, repo_ext.QueryUserMetricDataPage) | |||
| m.Get("/query_user_rank_list", operationReq, repo_ext.QueryRankingList) | |||
| m.Get("/query_user_static_page", operationReq, repo_ext.QueryUserStaticDataPage) | |||
| m.Get("/query_user_current_month", operationReq, repo_ext.QueryUserStaticCurrentMonth) | |||
| @@ -20,8 +20,10 @@ import ( | |||
| const DEFAULT_PAGE_SIZE = 10 | |||
| const DATE_FORMAT = "2006-01-02" | |||
| const MONTH_FORMAT = "2006-01" | |||
| const EXCEL_DATE_FORMAT = "20060102" | |||
| const CREATE_TIME_FORMAT = "2006/01/02 15:04:05" | |||
| const UPDATE_TIME_FORMAT = "2006-01-02 15:04:05" | |||
| type ProjectsPeriodData struct { | |||
| RecordBeginTime string `json:"recordBeginTime"` | |||
| @@ -60,6 +62,38 @@ type ProjectLatestData struct { | |||
| Top10 []UserInfo `json:"top10"` | |||
| } | |||
| type ProjectSummaryBaseData struct { | |||
| NumReposAdd int64 `json:"numReposAdd"` | |||
| NumRepoPublicAdd int64 `json:"numRepoPublicAdd"` | |||
| NumRepoPrivateAdd int64 `json:"numRepoPrivateAdd"` | |||
| NumRepoForkAdd int64 `json:"numRepoForkAdd"` | |||
| NumRepoMirrorAdd int64 `json:"numRepoMirrorAdd"` | |||
| NumRepoSelfAdd int64 `json:"numRepoSelfAdd"` | |||
| NumRepos int64 `json:"numRepos"` | |||
| CreatTime string `json:"creatTime"` | |||
| } | |||
| type ProjectSummaryData struct { | |||
| ProjectSummaryBaseData | |||
| NumRepoPublic int64 `json:"numRepoPublic"` | |||
| NumRepoPrivate int64 `json:"numRepoPrivate"` | |||
| NumRepoFork int64 `json:"numRepoFork"` | |||
| NumRepoMirror int64 `json:"numRepoMirror"` | |||
| NumRepoSelf int64 `json:"numRepoSelf"` | |||
| NumRepoOrgAdd int64 `json:"numRepoOrgAdd"` | |||
| NumRepoNotOrgAdd int64 `json:"numRepoNotOrgAdd"` | |||
| NumRepoOrg int64 `json:"numRepoOrg"` | |||
| NumRepoNotOrg int64 `json:"numRepoNotOrg"` | |||
| } | |||
| type ProjectSummaryPeriodData struct { | |||
| RecordBeginTime string `json:"recordBeginTime"` | |||
| TotalCount int64 `json:"totalCount"` | |||
| PageRecords []*ProjectSummaryBaseData `json:"pageRecords"` | |||
| } | |||
| func RestoreForkNumber(ctx *context.Context) { | |||
| repos, err := models.GetAllRepositories() | |||
| if err != nil { | |||
| @@ -73,6 +107,148 @@ func RestoreForkNumber(ctx *context.Context) { | |||
| ctx.JSON(http.StatusOK, struct{}{}) | |||
| } | |||
| func GetLatestProjectsSummaryData(ctx *context.Context) { | |||
| stat, err := models.GetLatest2SummaryStatistic() | |||
| data := ProjectSummaryData{} | |||
| if err == nil && len(stat) > 0 { | |||
| data.NumRepos = stat[0].NumRepos | |||
| data.NumRepoOrg = stat[0].NumRepoOrg | |||
| data.NumRepoNotOrg = stat[0].NumRepos - stat[0].NumRepoOrg | |||
| data.NumRepoFork = stat[0].NumRepoFork | |||
| data.NumRepoMirror = stat[0].NumRepoMirror | |||
| data.NumRepoSelf = stat[0].NumRepoSelf | |||
| data.NumRepoPrivate = stat[0].NumRepoPrivate | |||
| data.NumRepoPublic = stat[0].NumRepoPublic | |||
| data.CreatTime = stat[0].CreatedUnix.Format(UPDATE_TIME_FORMAT) | |||
| if len(stat) == 2 { | |||
| data.NumReposAdd = stat[0].NumRepos - stat[1].NumRepos | |||
| data.NumRepoOrgAdd = stat[0].NumRepoOrg - stat[1].NumRepoOrg | |||
| data.NumRepoNotOrgAdd = (stat[0].NumRepos - stat[0].NumRepoOrg) - (stat[1].NumRepos - stat[1].NumRepoOrg) | |||
| data.NumRepoForkAdd = stat[0].NumRepoFork - stat[1].NumRepoFork | |||
| data.NumRepoMirrorAdd = stat[0].NumRepoMirror - stat[1].NumRepoMirror | |||
| data.NumRepoSelfAdd = stat[0].NumRepoSelf - stat[1].NumRepoSelf | |||
| data.NumRepoPrivateAdd = stat[0].NumRepoPrivate - stat[1].NumRepoPrivate | |||
| data.NumRepoPublicAdd = stat[0].NumRepoPublic - stat[1].NumRepoPublic | |||
| } | |||
| } | |||
| ctx.JSON(200, data) | |||
| } | |||
| func GetProjectsSummaryData(ctx *context.Context) { | |||
| var datas = make([]*ProjectSummaryBaseData, 0) | |||
| recordBeginTime, err := getGrowthRecordBeginTime() | |||
| if err != nil { | |||
| log.Error("Can not get record begin time", err) | |||
| ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err")) | |||
| return | |||
| } | |||
| beginTime, endTime, err := getTimePeroid(ctx, recordBeginTime) | |||
| beginTime = beginTime.AddDate(0, 0, -1) | |||
| queryType := ctx.QueryTrim("type") | |||
| var count int64 | |||
| if queryType == "all" || queryType == "current_year" { | |||
| dates := getEndOfMonthDates(beginTime, endTime) | |||
| count, _ = models.GetSummaryStatisticByDateCount(dates) | |||
| stats, err := models.GetAllSummaryStatisticByDates(dates) | |||
| if err != nil { | |||
| log.Warn("can not get summary data", err) | |||
| } else { | |||
| for i, v := range stats { | |||
| if i == 0 { | |||
| continue | |||
| } | |||
| data := ProjectSummaryBaseData{} | |||
| setStatisticsData(&data, v, stats[i-1]) | |||
| createTime, _ := time.Parse(DATE_FORMAT, v.Date) | |||
| data.CreatTime = createTime.Format(MONTH_FORMAT) | |||
| datas = append(datas, &data) | |||
| } | |||
| } | |||
| } else { | |||
| count, _ = models.GetSummaryStatisticByTimeCount(beginTime, endTime) | |||
| stats, err := models.GetAllSummaryStatisticByTime(beginTime, endTime) | |||
| if err != nil { | |||
| log.Warn("can not get summary data", err) | |||
| } else { | |||
| for i, v := range stats { | |||
| if i == 0 { | |||
| continue | |||
| } | |||
| data := ProjectSummaryBaseData{} | |||
| setStatisticsData(&data, v, stats[i-1]) | |||
| data.CreatTime = v.Date | |||
| datas = append(datas, &data) | |||
| } | |||
| } | |||
| } | |||
| projectSummaryPeriodData := ProjectSummaryPeriodData{ | |||
| TotalCount: count - 1, | |||
| RecordBeginTime: recordBeginTime.Format(DATE_FORMAT), | |||
| PageRecords: reverse(datas), | |||
| } | |||
| ctx.JSON(200, projectSummaryPeriodData) | |||
| } | |||
| func reverse(datas []*ProjectSummaryBaseData ) []*ProjectSummaryBaseData { | |||
| for i := 0; i < len(datas)/2; i++ { | |||
| j := len(datas) - i - 1 | |||
| datas[i], datas[j] = datas[j], datas[i] | |||
| } | |||
| return datas | |||
| } | |||
| func setStatisticsData(data *ProjectSummaryBaseData, v *models.SummaryStatistic, stats *models.SummaryStatistic) { | |||
| data.NumReposAdd = v.NumRepos - stats.NumRepos | |||
| data.NumRepoPublicAdd = v.NumRepoPublic - stats.NumRepoPublic | |||
| data.NumRepoPrivateAdd = v.NumRepoPrivate - stats.NumRepoPrivate | |||
| data.NumRepoMirrorAdd = v.NumRepoMirror - stats.NumRepoMirror | |||
| data.NumRepoForkAdd = v.NumRepoFork - stats.NumRepoFork | |||
| data.NumRepoSelfAdd = v.NumRepoSelf - stats.NumRepoSelf | |||
| data.NumRepos = v.NumRepos | |||
| } | |||
| func getEndOfMonthDates(beginTime time.Time, endTime time.Time) []string { | |||
| var dates = []string{} | |||
| date := endOfMonth(beginTime.AddDate(0, -1, 0)) | |||
| dates = append(dates, date.Format(DATE_FORMAT)) | |||
| tempDate := endOfMonth(beginTime) | |||
| for { | |||
| if tempDate.Before(endTime) { | |||
| dates = append(dates, tempDate.Format(DATE_FORMAT)) | |||
| tempDate = endOfMonth(tempDate.AddDate(0, 0, 1)) | |||
| } else { | |||
| break | |||
| } | |||
| } | |||
| dates = append(dates, endTime.AddDate(0, 0, -1).Format(DATE_FORMAT)) | |||
| return dates | |||
| } | |||
| func endOfMonth(date time.Time) time.Time { | |||
| return date.AddDate(0, 1, -date.Day()) | |||
| } | |||
| func GetAllProjectsPeriodStatistics(ctx *context.Context) { | |||
| recordBeginTime, err := getRecordBeginTime() | |||
| @@ -210,6 +386,122 @@ func ServeAllProjectsPeriodStatisticsFile(ctx *context.Context) { | |||
| } | |||
| func GetProjectsSummaryDataFile(ctx *context.Context) { | |||
| recordBeginTime, err := getGrowthRecordBeginTime() | |||
| if err != nil { | |||
| log.Error("Can not get record begin time", err) | |||
| ctx.Error(http.StatusBadRequest, ctx.Tr("repo.record_begintime_get_err")) | |||
| return | |||
| } | |||
| beginTime, endTime, err := getTimePeroid(ctx, recordBeginTime) | |||
| beginTime = beginTime.AddDate(0, 0, -1) | |||
| if err != nil { | |||
| log.Error("Parameter is wrong", err) | |||
| ctx.Error(http.StatusBadRequest, ctx.Tr("repo.parameter_is_wrong")) | |||
| return | |||
| } | |||
| page := ctx.QueryInt("page") | |||
| if page <= 0 { | |||
| page = 1 | |||
| } | |||
| pageSize := 100 | |||
| if err != nil { | |||
| log.Error("Can not query the last updated time.", err) | |||
| ctx.Error(http.StatusBadRequest, ctx.Tr("repo.last_update_time_error")) | |||
| return | |||
| } | |||
| var projectAnalysis = ctx.Tr("repo.repo_stat_develop") | |||
| fileName := getSummaryFileName(ctx, beginTime, endTime, projectAnalysis) | |||
| f := excelize.NewFile() | |||
| index := f.NewSheet(projectAnalysis) | |||
| f.DeleteSheet("Sheet1") | |||
| for k, v := range allProjectsPeriodSummaryHeader(ctx) { | |||
| f.SetCellValue(projectAnalysis, k, v) | |||
| } | |||
| var total int64 | |||
| queryType := ctx.QueryTrim("type") | |||
| var datas = make([]*ProjectSummaryBaseData, 0) | |||
| if queryType == "all" || queryType == "current_year" { | |||
| dates := getEndOfMonthDates(beginTime, endTime) | |||
| total, _ = models.GetSummaryStatisticByDateCount(dates) | |||
| totalPage := getTotalPage(total, pageSize) | |||
| for i := 0; i < totalPage; i++ { | |||
| stats, err := models.GetSummaryStatisticByDates(dates, i+1, pageSize) | |||
| if err != nil { | |||
| log.Warn("can not get summary data", err) | |||
| } else { | |||
| for j, v := range stats { | |||
| if j == 0 { | |||
| continue | |||
| } | |||
| data := ProjectSummaryBaseData{} | |||
| setStatisticsData(&data, v, stats[j-1]) | |||
| createTime, _ := time.Parse(DATE_FORMAT, v.Date) | |||
| data.CreatTime = createTime.Format(MONTH_FORMAT) | |||
| datas = append(datas, &data) | |||
| } | |||
| } | |||
| } | |||
| } else { | |||
| total, _ = models.GetSummaryStatisticByTimeCount(beginTime, endTime) | |||
| totalPage := getTotalPage(total, pageSize) | |||
| for i := 0; i < totalPage; i++ { | |||
| stats, err := models.GetSummaryStatisticByTime(beginTime, endTime, i+1, pageSize) | |||
| if err != nil { | |||
| log.Warn("can not get summary data", err) | |||
| } else { | |||
| for j, v := range stats { | |||
| if j == 0 { | |||
| continue | |||
| } | |||
| data := ProjectSummaryBaseData{} | |||
| setStatisticsData(&data, v, stats[j-1]) | |||
| data.CreatTime = v.Date | |||
| datas = append(datas, &data) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| row := 2 | |||
| datas = reverse(datas) | |||
| for _, data := range datas { | |||
| for k, v := range allProjectsPeriodSummaryValues(row, data, ctx) { | |||
| f.SetCellValue(projectAnalysis, k, v) | |||
| } | |||
| row++ | |||
| } | |||
| f.SetActiveSheet(index) | |||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(fileName)) | |||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||
| f.WriteTo(ctx.Resp) | |||
| } | |||
| func ServeAllProjectsOpenIStatisticsFile(ctx *context.Context) { | |||
| page := ctx.QueryInt("page") | |||
| @@ -283,6 +575,9 @@ func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, p | |||
| } | |||
| if ctx.QueryTrim("type") == "all" { | |||
| baseName = baseName + ctx.Tr("repo.all") | |||
| } else if ctx.QueryTrim("type") == "last_month" { | |||
| baseName = baseName + beginTime.AddDate(0, 0, -1).Format(EXCEL_DATE_FORMAT) + "_" + endTime.AddDate(0, 0, -2).Format(EXCEL_DATE_FORMAT) | |||
| } else { | |||
| baseName = baseName + beginTime.AddDate(0, 0, -1).Format(EXCEL_DATE_FORMAT) + "_" + endTime.AddDate(0, 0, -1).Format(EXCEL_DATE_FORMAT) | |||
| } | |||
| @@ -290,6 +585,22 @@ func getFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, p | |||
| return frontName | |||
| } | |||
| func getSummaryFileName(ctx *context.Context, beginTime time.Time, endTime time.Time, projectAnalysis string) string { | |||
| baseName := projectAnalysis + "_" | |||
| if ctx.QueryTrim("type") == "all" { | |||
| baseName = baseName + ctx.Tr("repo.all") | |||
| } else if ctx.QueryTrim("type") == "current_year" { | |||
| baseName = baseName + ctx.Tr("repo.current_year") | |||
| } else if ctx.QueryTrim("type") == "last_month" { | |||
| baseName = baseName + beginTime.Format(EXCEL_DATE_FORMAT) + "_" + endTime.AddDate(0, 0, -2).Format(EXCEL_DATE_FORMAT) | |||
| } else { | |||
| baseName = baseName + beginTime.Format(EXCEL_DATE_FORMAT) + "_" + endTime.AddDate(0, 0, -1).Format(EXCEL_DATE_FORMAT) | |||
| } | |||
| frontName := baseName + ".xlsx" | |||
| return frontName | |||
| } | |||
| func allProjectsPeroidHeader(ctx *context.Context) map[string]string { | |||
| return map[string]string{"A1": ctx.Tr("admin.repos.id"), "B1": ctx.Tr("admin.repos.projectName"), "C1": ctx.Tr("repo.owner"), "D1": ctx.Tr("admin.repos.isPrivate"), "E1": ctx.Tr("admin.repos.openi"), "F1": ctx.Tr("admin.repos.visit"), "G1": ctx.Tr("admin.repos.download"), "H1": ctx.Tr("admin.repos.pr"), "I1": ctx.Tr("admin.repos.commit"), | |||
| @@ -297,6 +608,19 @@ func allProjectsPeroidHeader(ctx *context.Context) map[string]string { | |||
| } | |||
| func allProjectsPeriodSummaryHeader(ctx *context.Context) map[string]string { | |||
| return map[string]string{"A1": ctx.Tr("repo.date"), "B1": ctx.Tr("repo.repo_add"), "C1": ctx.Tr("repo.repo_total"), "D1": ctx.Tr("repo.repo_public_add"), "E1": ctx.Tr("repo.repo_private_add"), "F1": ctx.Tr("repo.repo_self_add"), "G1": ctx.Tr("repo.repo_fork_add"), "H1": ctx.Tr("repo.repo_mirror_add")} | |||
| } | |||
| func allProjectsPeriodSummaryValues(row int, rs *ProjectSummaryBaseData, ctx *context.Context) map[string]string { | |||
| return map[string]string{getCellName("A", row): rs.CreatTime, getCellName("B", row): strconv.FormatInt(rs.NumReposAdd, 10), getCellName("C", row): strconv.FormatInt(rs.NumRepos, 10), getCellName("D", row): strconv.FormatInt(rs.NumRepoPublicAdd, 10), getCellName("E", row): strconv.FormatInt(rs.NumRepoPrivateAdd, 10), | |||
| getCellName("F", row): strconv.FormatInt(rs.NumRepoSelfAdd, 10), getCellName("G", row): strconv.FormatInt(rs.NumRepoForkAdd, 10), getCellName("H", row): strconv.FormatInt(rs.NumRepoMirrorAdd, 10), | |||
| } | |||
| } | |||
| func allProjectsPeroidValues(row int, rs *models.RepoStatistic, ctx *context.Context) map[string]string { | |||
| return map[string]string{getCellName("A", row): strconv.FormatInt(rs.RepoID, 10), getCellName("B", row): rs.DisplayName(), getCellName("C", row): rs.OwnerName, getCellName("D", row): getBoolDisplay(rs.IsPrivate, ctx), getCellName("E", row): strconv.FormatFloat(rs.RadarTotal, 'f', 2, 64), | |||
| getCellName("F", row): strconv.FormatInt(rs.NumVisits, 10), getCellName("G", row): strconv.FormatInt(rs.NumDownloads, 10), getCellName("H", row): strconv.FormatInt(rs.NumPulls, 10), getCellName("I", row): strconv.FormatInt(rs.NumCommits, 10), | |||
| @@ -633,6 +957,10 @@ func getRecordBeginTime() (time.Time, error) { | |||
| return time.ParseInLocation(DATE_FORMAT, setting.RadarMap.RecordBeginTime, time.Local) | |||
| } | |||
| func getGrowthRecordBeginTime() (time.Time, error) { | |||
| return time.ParseInLocation(DATE_FORMAT, setting.RadarMap.GrowthBeginTime, time.Local) | |||
| } | |||
| func getTotalPage(total int64, pageSize int) int { | |||
| another := 0 | |||
| @@ -8,6 +8,7 @@ package routers | |||
| import ( | |||
| "bytes" | |||
| "net/http" | |||
| "strconv" | |||
| "strings" | |||
| "code.gitea.io/gitea/services/repository" | |||
| @@ -92,6 +93,8 @@ func setRecommendURL(ctx *context.Context) { | |||
| ctx.Data["page_dev_yunlao_desc3"] = ctx.Tr("home.page_dev_yunlao_desc3") | |||
| ctx.Data["page_dev_yunlao_desc4"] = ctx.Tr("home.page_dev_yunlao_desc4") | |||
| ctx.Data["page_dev_yunlao_apply"] = ctx.Tr("home.page_dev_yunlao_apply") | |||
| ctx.Data["page_recommend_activity"] = ctx.Tr("home.page_recommend_activity") | |||
| ctx.Data["page_recommend_activity_desc"] = ctx.Tr("home.page_recommend_activity_desc") | |||
| } | |||
| func Dashboard(ctx *context.Context) { | |||
| @@ -602,7 +605,32 @@ func ExploreImages(ctx *context.Context) { | |||
| ctx.HTML(200, tplExploreImages) | |||
| } | |||
| func ExploreDataAnalysisUserTrend(ctx *context.Context) { | |||
| ctx.Data["url_params"]="UserTrend" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| func ExploreDataAnalysisUserAnalysis(ctx *context.Context) { | |||
| ctx.Data["url_params"]="UserAnalysis" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| func ExploreDataAnalysisProTrend(ctx *context.Context) { | |||
| ctx.Data["url_params"]="ProTrend" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| func ExploreDataAnalysisProAnalysis(ctx *context.Context) { | |||
| ctx.Data["url_params"]="ProAnalysis" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| func ExploreDataAnalysisOverview(ctx *context.Context) { | |||
| ctx.Data["url_params"]="Overview" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| func ExploreDataAnalysisBrainAnalysis(ctx *context.Context) { | |||
| ctx.Data["url_params"]="BrainAnalysis" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| func ExploreDataAnalysis(ctx *context.Context) { | |||
| ctx.Data["url_params"]="" | |||
| ctx.HTML(200, tplExploreExploreDataAnalysis) | |||
| } | |||
| @@ -640,6 +668,87 @@ func GetRecommendOrg() ([]map[string]interface{}, error) { | |||
| } | |||
| return resultOrg, nil | |||
| } | |||
| func GetImageInfo() ([]map[string]interface{}, error) { | |||
| url := setting.RecommentRepoAddr + "picture_info" | |||
| result, err := repository.RecommendFromPromote(url) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| imageInfo := make([]map[string]interface{}, 0) | |||
| for i := 0; i < (len(result) - 1); i++ { | |||
| line := result[i] | |||
| imageMap := make(map[string]interface{}) | |||
| if line[0:4] == "url=" { | |||
| url := line[4:] | |||
| imageMap["url"] = url | |||
| if result[i+1][0:11] == "image_link=" { | |||
| image_link := result[i+1][11:] | |||
| imageMap["image_link"] = image_link | |||
| } | |||
| } | |||
| imageInfo = append(imageInfo, imageMap) | |||
| i = i + 1 | |||
| } | |||
| return imageInfo, nil | |||
| } | |||
| func GetRankUser(index string) ([]map[string]interface{}, error) { | |||
| url := setting.RecommentRepoAddr + "user_rank_" + index | |||
| result, err := repository.RecommendFromPromote(url) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| resultOrg := make([]map[string]interface{}, 0) | |||
| for _, userRank := range result { | |||
| tmpIndex := strings.Index(userRank, " ") | |||
| userName := userRank | |||
| score := 0 | |||
| if tmpIndex != -1 { | |||
| userName = userRank[0:tmpIndex] | |||
| tmpScore, err := strconv.Atoi(userRank[tmpIndex+1:]) | |||
| if err != nil { | |||
| log.Info("convert to int error.") | |||
| } | |||
| score = tmpScore | |||
| } | |||
| user, err := models.GetUserByName(userName) | |||
| if err == nil { | |||
| userMap := make(map[string]interface{}) | |||
| userMap["Name"] = user.Name | |||
| userMap["Description"] = user.Description | |||
| userMap["FullName"] = user.FullName | |||
| userMap["HomeLink"] = user.HomeLink() | |||
| userMap["ID"] = user.ID | |||
| userMap["Avatar"] = user.RelAvatarLink() | |||
| userMap["Score"] = score | |||
| resultOrg = append(resultOrg, userMap) | |||
| } else { | |||
| log.Info("query user error," + err.Error()) | |||
| } | |||
| } | |||
| return resultOrg, nil | |||
| } | |||
| func GetImageInfoFromPromote(ctx *context.Context) { | |||
| imageInfo, err := GetImageInfo() | |||
| if err != nil { | |||
| ctx.ServerError("500", err) | |||
| return | |||
| } | |||
| ctx.JSON(200, imageInfo) | |||
| } | |||
| func GetUserRankFromPromote(ctx *context.Context) { | |||
| index := ctx.Params("index") | |||
| resultUserRank, err := GetRankUser(index) | |||
| if err != nil { | |||
| ctx.ServerError("500", err) | |||
| return | |||
| } | |||
| ctx.JSON(200, resultUserRank) | |||
| } | |||
| func RecommendOrgFromPromote(ctx *context.Context) { | |||
| resultOrg, err := GetRecommendOrg() | |||
| @@ -199,7 +199,6 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) { | |||
| env = append(env, | |||
| private.GitQuarantinePath+"="+opts.GitQuarantinePath) | |||
| } | |||
| for i := range opts.OldCommitIDs { | |||
| oldCommitID := opts.OldCommitIDs[i] | |||
| newCommitID := opts.NewCommitIDs[i] | |||
| @@ -368,6 +367,24 @@ func HookPreReceive(ctx *macaron.Context, opts private.HookOptions) { | |||
| ctx.PlainText(http.StatusOK, []byte("ok")) | |||
| } | |||
| // HookEnv | |||
| func HookEnv(ctx *macaron.Context) { | |||
| ownerName := ctx.Params(":owner") | |||
| repoName := ctx.Params(":repo") | |||
| log.Info("try to get hook env.ownerName=%s repoName=%s", ownerName, repoName) | |||
| repo, err := models.GetRepositoryByOwnerAndName(ownerName, repoName) | |||
| if err != nil { | |||
| log.Error("Unable to get repository: %s/%s Error: %v", ownerName, repoName, err) | |||
| ctx.JSON(http.StatusInternalServerError, map[string]interface{}{ | |||
| "err": err.Error(), | |||
| }) | |||
| return | |||
| } | |||
| result := make(map[string]string, 1) | |||
| result[models.EnvRepoSize] = fmt.Sprint(repo.Size) | |||
| ctx.JSON(http.StatusOK, &private.HookEnvResult{Config: result}) | |||
| } | |||
| // HookPostReceive updates services and users | |||
| func HookPostReceive(ctx *macaron.Context, opts private.HookOptions) { | |||
| ownerName := ctx.Params(":owner") | |||
| @@ -6,9 +6,10 @@ | |||
| package private | |||
| import ( | |||
| "code.gitea.io/gitea/routers/repo" | |||
| "strings" | |||
| "code.gitea.io/gitea/routers/repo" | |||
| "code.gitea.io/gitea/modules/log" | |||
| "code.gitea.io/gitea/modules/private" | |||
| "code.gitea.io/gitea/modules/setting" | |||
| @@ -38,6 +39,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/hook/pre-receive/:owner/:repo", bind(private.HookOptions{}), HookPreReceive) | |||
| m.Post("/hook/post-receive/:owner/:repo", bind(private.HookOptions{}), HookPostReceive) | |||
| m.Post("/hook/set-default-branch/:owner/:repo/:branch", SetDefaultBranch) | |||
| m.Get("/hook/env/:owner/:repo", HookEnv) | |||
| m.Get("/serv/none/:keyid", ServNoCommand) | |||
| m.Get("/serv/command/:keyid/:owner/:repo", ServCommand) | |||
| m.Post("/manager/shutdown", Shutdown) | |||
| @@ -45,7 +47,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Post("/manager/flush-queues", bind(private.FlushOptions{}), FlushQueues) | |||
| m.Post("/tool/update_all_repo_commit_cnt", UpdateAllRepoCommitCnt) | |||
| m.Post("/tool/repo_stat/:date", RepoStatisticManually) | |||
| m.Post("/tool/user_stat/:date", UserStatisticManually) | |||
| m.Get("/tool/org_stat", OrgStatisticManually) | |||
| m.Post("/tool/update_repo_visit/:date", UpdateRepoVisit) | |||
| m.Post("/task/history_handle/duration", repo.HandleTaskWithNoDuration) | |||
| @@ -45,6 +45,11 @@ func RepoStatisticManually(ctx *macaron.Context) { | |||
| repo.TimingCountDataByDate(date) | |||
| } | |||
| func UserStatisticManually(ctx *macaron.Context) { | |||
| date := ctx.Params("date") | |||
| repo.TimingCountDataByDate(date) | |||
| } | |||
| func OrgStatisticManually() { | |||
| models.UpdateOrgStatistics() | |||
| } | |||
| @@ -188,6 +188,8 @@ func cloudBrainNewDataPrepare(ctx *context.Context) error { | |||
| ctx.Data["cloudbraintype"] = models.TypeCloudBrainOne | |||
| ctx.Data["benchmarkMode"] = ctx.Query("benchmarkMode") | |||
| return nil | |||
| } | |||
| @@ -249,7 +251,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| return | |||
| } | |||
| if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) && jobType != string(models.JobTypeTrain) { | |||
| if jobType != string(models.JobTypeBenchmark) && jobType != string(models.JobTypeDebug) && jobType != string(models.JobTypeTrain) { | |||
| log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("jobtype error", tpl, &form) | |||
| @@ -266,7 +268,7 @@ func CloudBrainCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| if count >= 1 { | |||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("you have already a running or waiting task, can not create more", tpl, &form) | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form) | |||
| return | |||
| } | |||
| } | |||
| @@ -379,7 +381,7 @@ func CloudBrainRestart(ctx *context.Context) { | |||
| if count >= 1 { | |||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||
| resultCode = "-1" | |||
| errorMsg = "you have already a running or waiting task, can not create more" | |||
| errorMsg = ctx.Tr("repo.cloudbrain.morethanonejob") | |||
| break | |||
| } | |||
| } | |||
| @@ -491,34 +493,22 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
| } | |||
| } | |||
| taskRoles := jobRes.TaskRoles | |||
| if jobRes.JobStatus.State != string(models.JobFailed) { | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| ctx.Data["taskRes"] = taskRes | |||
| task.Status = taskRes.TaskStatuses[0].State | |||
| task.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||
| task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||
| models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | |||
| if task.DeletedAt.IsZero() { //normal record | |||
| err = models.UpdateJob(task) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| return | |||
| } | |||
| } else { //deleted record | |||
| taskRes, _ := models.ConvertToTaskPod(taskRoles[cloudbrain.SubTaskName].(map[string]interface{})) | |||
| ctx.Data["taskRes"] = taskRes | |||
| ctx.Data["ExitDiagnostics"] = taskRes.TaskStatuses[0].ExitDiagnostics | |||
| task.Status = taskRes.TaskStatuses[0].State | |||
| task.ContainerID = taskRes.TaskStatuses[0].ContainerID | |||
| task.ContainerIp = taskRes.TaskStatuses[0].ContainerIP | |||
| models.ParseAndSetDurationFromCloudBrainOne(jobRes, task) | |||
| if task.DeletedAt.IsZero() { //normal record | |||
| err = models.UpdateJob(task) | |||
| if err != nil { | |||
| ctx.Data["error"] = err.Error() | |||
| return | |||
| } | |||
| } else { | |||
| task.Status = jobRes.JobStatus.State | |||
| taskRes := models.TaskPod{TaskStatuses: []models.TaskStatuses{ | |||
| { | |||
| State: jobRes.JobStatus.State, | |||
| }, | |||
| }} | |||
| ctx.Data["taskRes"] = taskRes | |||
| jobRes.JobStatus.StartTime = time.Unix(int64(task.CreatedUnix), 0).Format("2006-01-02 15:04:05") | |||
| jobRes.JobStatus.EndTime = time.Unix(int64(task.UpdatedUnix), 0).Format("2006-01-02 15:04:05") | |||
| } else { //deleted record | |||
| } | |||
| ctx.Data["result"] = jobRes | |||
| @@ -536,6 +526,7 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
| for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType { | |||
| if task.BenchmarkTypeID == benchmarkType.Id { | |||
| ctx.Data["BenchmarkTypeName"] = benchmarkType.First | |||
| task.BenchmarkTypeName = benchmarkType.First | |||
| for _, benchmarkChildType := range benchmarkType.Second { | |||
| if task.BenchmarkChildTypeID == benchmarkChildType.Id { | |||
| ctx.Data["BenchmarkChildTypeName"] = benchmarkChildType.Value | |||
| @@ -546,6 +537,19 @@ func cloudBrainShow(ctx *context.Context, tpName base.TplName, jobType models.Jo | |||
| } | |||
| } | |||
| } | |||
| if task.JobType == string(models.JobTypeBenchmark) { | |||
| task.BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.algorithm") | |||
| } else if task.JobType == string(models.JobTypeSnn4imagenet) || task.JobType == string(models.JobTypeBrainScore) { | |||
| task.BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.model") | |||
| task.BenchmarkTypeName = task.JobType | |||
| ctx.Data["BenchmarkTypeName"] = task.JobType | |||
| if task.JobType == string(models.JobTypeBrainScore) { | |||
| ctx.Data["BenchmarkChildTypeName"] = getBrainRegion(task.BenchmarkChildTypeID) | |||
| } | |||
| } | |||
| if task.TrainJobDuration == "" { | |||
| if task.Duration == 0 { | |||
| var duration int64 | |||
| @@ -1397,6 +1401,8 @@ func SyncCloudbrainStatus() { | |||
| var maxDuration int64 | |||
| if task.JobType == string(models.JobTypeBenchmark) { | |||
| maxDuration = setting.BenchmarkMaxDuration | |||
| } else if task.JobType == string(models.JobTypeSnn4imagenet) || task.JobType == string(models.JobTypeBrainScore) { | |||
| maxDuration = setting.ModelBenchmarkMaxDuration | |||
| } else { | |||
| maxDuration = setting.MaxDuration | |||
| } | |||
| @@ -1646,7 +1652,7 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||
| } | |||
| var jobTypes []string | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark)) | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| Page: page, | |||
| @@ -1676,8 +1682,21 @@ func CloudBrainBenchmarkIndex(ctx *context.Context) { | |||
| } | |||
| ciTasks[i].TrainJobDuration = models.ConvertDurationToStr(ciTasks[i].Duration) | |||
| } | |||
| ciTasks[i].BenchmarkTypeName = "" | |||
| if ciTasks[i].JobType == string(models.JobTypeBenchmark) { | |||
| ciTasks[i].BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.algorithm") | |||
| } else if ciTasks[i].JobType == string(models.JobTypeSnn4imagenet) || ciTasks[i].JobType == string(models.JobTypeBrainScore) { | |||
| ciTasks[i].BenchmarkType = ctx.Tr("repo.cloudbrain.benchmark.model") | |||
| ciTasks[i].BenchmarkTypeName = ciTasks[i].JobType | |||
| if ciTasks[i].JobType == string(models.JobTypeSnn4imagenet) { | |||
| ciTasks[i].BenchmarkTypeRankLink = setting.Snn4imagenetServerHost | |||
| } else { | |||
| ciTasks[i].BenchmarkTypeRankLink = setting.BrainScoreServerHost | |||
| } | |||
| } | |||
| if task.BenchmarkTypeID > 0 { | |||
| for _, benchmarkType := range GetBenchmarkTypes(ctx).BenchmarkType { | |||
| if task.BenchmarkTypeID == benchmarkType.Id { | |||
| @@ -1813,6 +1832,16 @@ func getBenchmarkResourceSpec(resourceSpecID int) (int, error) { | |||
| } | |||
| func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| jobType := form.JobType | |||
| if jobType == string(models.JobTypeBenchmark) { | |||
| BenchMarkAlgorithmCreate(ctx, form) | |||
| } else { | |||
| ModelBenchmarkCreate(ctx, form) | |||
| } | |||
| } | |||
| func BenchMarkAlgorithmCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| @@ -1877,7 +1906,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| return | |||
| } | |||
| count, err := models.GetCloudbrainCountByUserID(ctx.User.ID, string(models.JobTypeBenchmark)) | |||
| count, err := models.GetBenchmarkCountByUserID(ctx.User.ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| @@ -1887,7 +1916,7 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| if count >= 1 { | |||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("you have already a running or waiting task, can not create more", tplCloudBrainBenchmarkNew, &form) | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| } | |||
| @@ -1965,10 +1994,119 @@ func CloudBrainBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainF | |||
| ctx.RenderWithErr(err.Error(), tplCloudBrainBenchmarkNew, &form) | |||
| return | |||
| } | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark") | |||
| } | |||
| func ModelBenchmarkCreate(ctx *context.Context, form auth.CreateCloudBrainForm) { | |||
| ctx.Data["PageIsCloudBrain"] = true | |||
| displayJobName := form.DisplayJobName | |||
| jobName := util.ConvertDisplayJobNameToJobName(displayJobName) | |||
| image := form.Image | |||
| uuid := form.Attachment | |||
| jobType := form.JobType | |||
| gpuQueue := form.GpuType | |||
| codePath := setting.JobPath + jobName + cloudbrain.CodeMountPath | |||
| resourceSpecId := form.ResourceSpecId | |||
| branchName := cloudbrain.DefaultBranchName | |||
| repo := ctx.Repo.Repository | |||
| tpl := tplCloudBrainBenchmarkNew | |||
| command := cloudbrain.Command | |||
| tasks, err := models.GetCloudbrainsByDisplayJobName(repo.ID, jobType, displayJobName) | |||
| if err == nil { | |||
| if len(tasks) != 0 { | |||
| log.Error("the job name did already exist", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("the job name did already exist", tpl, &form) | |||
| return | |||
| } | |||
| } else { | |||
| if !models.IsErrJobNotExist(err) { | |||
| log.Error("system error, %v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tpl, &form) | |||
| return | |||
| } | |||
| } | |||
| if !jobNamePattern.MatchString(displayJobName) { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain_jobname_err"), tpl, &form) | |||
| return | |||
| } | |||
| if jobType != string(models.JobTypeSnn4imagenet) && jobType != string(models.JobTypeBrainScore) { | |||
| log.Error("jobtype error:", jobType, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("jobtype error", tpl, &form) | |||
| return | |||
| } | |||
| count, err := models.GetBenchmarkCountByUserID(ctx.User.ID) | |||
| if err != nil { | |||
| log.Error("GetCloudbrainCountByUserID failed:%v", err, ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr("system error", tpl, &form) | |||
| return | |||
| } else { | |||
| if count >= 1 { | |||
| log.Error("the user already has running or waiting task", ctx.Data["MsgID"]) | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(ctx.Tr("repo.cloudbrain.morethanonejob"), tpl, &form) | |||
| return | |||
| } | |||
| } | |||
| downloadCode(repo, codePath, branchName) | |||
| uploadCodeToMinio(codePath+"/", jobName, cloudbrain.CodeMountPath+"/") | |||
| modelPath := setting.JobPath + jobName + cloudbrain.ModelMountPath + "/" | |||
| mkModelPath(modelPath) | |||
| uploadCodeToMinio(modelPath, jobName, cloudbrain.ModelMountPath+"/") | |||
| snn4imagenetPath := setting.JobPath + jobName + cloudbrain.Snn4imagenetMountPath | |||
| if setting.IsSnn4imagenetEnabled && jobType == string(models.JobTypeSnn4imagenet) { | |||
| downloadRateCode(repo, jobName, setting.Snn4imagenetOwner, setting.Snn4imagenetName, snn4imagenetPath, "", "") | |||
| uploadCodeToMinio(snn4imagenetPath+"/", jobName, cloudbrain.Snn4imagenetMountPath+"/") | |||
| command = fmt.Sprintf(cloudbrain.Snn4imagenetCommand, displayJobName, trimSpaceNewlineInString(form.Description)) | |||
| } | |||
| benchmarkChildTypeID := 0 | |||
| brainScorePath := setting.JobPath + jobName + cloudbrain.BrainScoreMountPath | |||
| if setting.IsBrainScoreEnabled && jobType == string(models.JobTypeBrainScore) { | |||
| downloadRateCode(repo, jobName, setting.BrainScoreOwner, setting.BrainScoreName, brainScorePath, "", "") | |||
| uploadCodeToMinio(brainScorePath+"/", jobName, cloudbrain.BrainScoreMountPath+"/") | |||
| benchmarkChildTypeID = form.BenchmarkChildTypeID | |||
| command = fmt.Sprintf(cloudbrain.BrainScoreCommand, getBrainRegion(benchmarkChildTypeID), displayJobName, trimSpaceNewlineInString(form.Description)) | |||
| } | |||
| err = cloudbrain.GenerateTask(ctx, displayJobName, jobName, image, command, uuid, storage.GetMinioPath(jobName, cloudbrain.CodeMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.ModelMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.BenchMarkMountPath+"/"), storage.GetMinioPath(jobName, cloudbrain.Snn4imagenetMountPath+"/"), | |||
| storage.GetMinioPath(jobName, cloudbrain.BrainScoreMountPath+"/"), jobType, gpuQueue, form.Description, branchName, form.BootFile, form.Params, | |||
| 0, benchmarkChildTypeID, resourceSpecId) | |||
| if err != nil { | |||
| cloudBrainNewDataPrepare(ctx) | |||
| ctx.RenderWithErr(err.Error(), tpl, &form) | |||
| return | |||
| } | |||
| ctx.Redirect(setting.AppSubURL + ctx.Repo.RepoLink + "/cloudbrain/benchmark") | |||
| } | |||
| func getBrainRegion(benchmarkChildTypeID int) string { | |||
| values := []string{"V1", "V2", "V4", "IT"} | |||
| return values[benchmarkChildTypeID] | |||
| } | |||
| func trimSpaceNewlineInString(s string) string { | |||
| re := regexp.MustCompile(`\r?\n`) | |||
| return re.ReplaceAllString(s, " ") | |||
| } | |||
| func BenchmarkDel(ctx *context.Context) { | |||
| if err := deleteCloudbrainJob(ctx); err != nil { | |||
| log.Error("deleteCloudbrainJob failed: %v", err, ctx.Data["msgID"]) | |||
| @@ -5,10 +5,12 @@ | |||
| package repo | |||
| import ( | |||
| "code.gitea.io/gitea/routers/response" | |||
| repo_service "code.gitea.io/gitea/services/repository" | |||
| "encoding/json" | |||
| "fmt" | |||
| "io/ioutil" | |||
| "net/http" | |||
| "path" | |||
| "path/filepath" | |||
| "strings" | |||
| @@ -795,3 +797,102 @@ func GetClosestParentWithFiles(treePath string, commit *git.Commit) string { | |||
| } | |||
| return treePath | |||
| } | |||
| // RenameFilePost response for editing file | |||
| func RenameFilePost(ctx *context.Context, form auth.RenameRepoFileForm) { | |||
| renameFilePost(ctx, form) | |||
| } | |||
| func renameFilePost(ctx *context.Context, form auth.RenameRepoFileForm) { | |||
| if form.TreePath == "" || form.LastCommit == "" { | |||
| ctx.JSON(http.StatusOK, response.ServerError("param error")) | |||
| return | |||
| } | |||
| if form.TreePath == ctx.Repo.TreePath { | |||
| ctx.JSON(http.StatusOK, response.Success()) | |||
| return | |||
| } | |||
| canCommit := renderCommitRights(ctx) | |||
| branchName := ctx.Repo.BranchName | |||
| if ctx.HasError() { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Flash.ErrorMsg)) | |||
| return | |||
| } | |||
| // Cannot commit to a an existing branch if user doesn't have rights | |||
| if branchName == ctx.Repo.BranchName && !canCommit { | |||
| ctx.Data["Err_NewBranchName"] = true | |||
| ctx.Data["commit_choice"] = frmCommitChoiceNewBranch | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.cannot_commit_to_protected_branch", branchName))) | |||
| return | |||
| } | |||
| message := ctx.Tr("repo.editor.rename", ctx.Repo.TreePath, form.TreePath) | |||
| if err := repofiles.RenameRepoFile(ctx.Repo.Repository, ctx.User, &repofiles.RenameRepoFileOptions{ | |||
| LastCommitID: form.LastCommit, | |||
| BranchName: branchName, | |||
| FromTreePath: ctx.Repo.TreePath, | |||
| TreePath: form.TreePath, | |||
| Message: message, | |||
| }); err != nil { | |||
| // This is where we handle all the errors thrown by repofiles.CreateOrUpdateRepoFile | |||
| if git.IsErrNotExist(err) { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.file_or_directory_editing_no_longer_exists", ctx.Repo.TreePath))) | |||
| } else if models.IsErrLFSFileLocked(err) { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.file_or_directory_editing_no_longer_exists", ctx.Tr("repo.editor.upload_file_is_locked", err.(models.ErrLFSFileLocked).Path, err.(models.ErrLFSFileLocked).UserName)))) | |||
| } else if models.IsErrFilenameInvalid(err) { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.filename_is_invalid", form.TreePath))) | |||
| } else if models.IsErrFilePathInvalid(err) { | |||
| if fileErr, ok := err.(models.ErrFilePathInvalid); ok { | |||
| switch fileErr.Type { | |||
| case git.EntryModeSymlink: | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.file_is_a_symlink", fileErr.Path))) | |||
| case git.EntryModeTree: | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.filename_is_a_directory", fileErr.Path))) | |||
| case git.EntryModeBlob: | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.directory_is_a_file", fileErr.Path))) | |||
| default: | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| } | |||
| } else { | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| } | |||
| } else if models.IsErrRepoFileAlreadyExists(err) { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.file_already_exists", form.TreePath))) | |||
| } else if git.IsErrBranchNotExist(err) { | |||
| // For when a user adds/updates a file to a branch that no longer exists | |||
| if branchErr, ok := err.(git.ErrBranchNotExist); ok { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.branch_does_not_exist", branchErr.Name))) | |||
| } else { | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| } | |||
| } else if models.IsErrBranchAlreadyExists(err) { | |||
| // For when a user specifies a new branch that already exists | |||
| ctx.Data["Err_NewBranchName"] = true | |||
| if branchErr, ok := err.(models.ErrBranchAlreadyExists); ok { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName))) | |||
| } else { | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| ctx.Error(500, err.Error()) | |||
| } | |||
| } else if models.IsErrCommitIDDoesNotMatch(err) { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.file_changed_while_renaming"))) | |||
| } else if git.IsErrPushOutOfDate(err) { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.file_changed_while_renaming"))) | |||
| } else if git.IsErrPushRejected(err) { | |||
| errPushRej := err.(*git.ErrPushRejected) | |||
| if len(errPushRej.Message) == 0 { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.push_rejected_no_message"))) | |||
| } else { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.push_rejected", utils.SanitizeFlashErrorString(errPushRej.Message)))) | |||
| } | |||
| } else { | |||
| ctx.JSON(http.StatusOK, response.ServerError(ctx.Tr("repo.editor.fail_to_update_file", form.TreePath, utils.SanitizeFlashErrorString(err.Error())))) | |||
| } | |||
| return | |||
| } | |||
| ctx.JSON(http.StatusOK, response.Success()) | |||
| } | |||
| @@ -76,7 +76,7 @@ func DebugJobIndex(ctx *context.Context) { | |||
| } | |||
| var jobTypes []string | |||
| jobTypes = append(jobTypes, string(models.JobTypeSnn4imagenet), string(models.JobTypeBrainScore), string(models.JobTypeDebug)) | |||
| jobTypes = append(jobTypes, string(models.JobTypeDebug)) | |||
| ciTasks, count, err := models.Cloudbrains(&models.CloudbrainsOptions{ | |||
| ListOptions: models.ListOptions{ | |||
| Page: page, | |||
| @@ -60,6 +60,12 @@ func SummaryStatisticDaily(date string) { | |||
| } | |||
| selfRepositoryNumber := repositoryNumer - mirrorRepositoryNumber - forkRepositoryNumber | |||
| organizationRepoNumber, err := models.GetAllOrgRepositoriesCount() | |||
| if err != nil { | |||
| log.Error("can not get org repository number", err) | |||
| organizationRepoNumber = 0 | |||
| } | |||
| //repository size | |||
| repositorySize, err := models.GetAllRepositoriesSize() | |||
| if err != nil { | |||
| @@ -99,6 +105,7 @@ func SummaryStatisticDaily(date string) { | |||
| NumRepoPrivate: privateRepositoryNumer, | |||
| NumRepoPublic: publicRepositoryNumer, | |||
| NumRepoSelf: selfRepositoryNumber, | |||
| NumRepoOrg: organizationRepoNumber, | |||
| NumRepoBigModel: topicsCount[0], | |||
| NumRepoAI: topicsCount[1], | |||
| NumRepoVision: topicsCount[2], | |||
| @@ -19,6 +19,59 @@ const ( | |||
| PAGE_SIZE = 2000 | |||
| ) | |||
| func getUserMetricsExcelHeader(ctx *context.Context) map[string]string { | |||
| excelHeader := make([]string, 0) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.date")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistandactiveuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.hasactivateuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newregistnotactiveuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.newuseractiveindex")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalregistuser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalactiveduser")) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.metrics.totalhasactivityuser")) | |||
| excelHeaderMap := make(map[string]string, 0) | |||
| var i byte | |||
| i = 0 | |||
| for _, value := range excelHeader { | |||
| excelColumn := getColumn(i) + fmt.Sprint(1) | |||
| excelHeaderMap[excelColumn] = value | |||
| i++ | |||
| } | |||
| return excelHeaderMap | |||
| } | |||
| func writeUserMetricsExcel(row int, xlsx *excelize.File, sheetName string, userMetrics *models.UserMetrics) { | |||
| rows := fmt.Sprint(row) | |||
| var tmp byte | |||
| tmp = 0 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.DisplayDate) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.ActivateRegistUser+userMetrics.NotActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.ActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.RegistActivityUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.NotActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| t := userMetrics.ActivateIndex * 100 | |||
| value := "-" | |||
| if t < 100 && t > 0 { | |||
| value = fmt.Sprintf("%.2f", t) + "%" | |||
| } else if t >= 100 { | |||
| value = "100%" | |||
| } | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, value) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalActivateRegistUser) | |||
| tmp = tmp + 1 | |||
| xlsx.SetCellValue(sheetName, getColumn(tmp)+rows, userMetrics.TotalHasActivityUser) | |||
| } | |||
| func getExcelHeader(ctx *context.Context) map[string]string { | |||
| excelHeader := make([]string, 0) | |||
| excelHeader = append(excelHeader, ctx.Tr("user.static.id")) | |||
| @@ -196,20 +249,73 @@ func queryUserDataPage(ctx *context.Context, tableName string, queryObj interfac | |||
| mapInterface := make(map[string]interface{}) | |||
| mapInterface["data"] = re | |||
| mapInterface["count"] = count | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| } | |||
| } | |||
| func QueryMetrics(ctx *context.Context) { | |||
| startDate := ctx.Query("startDate") | |||
| endDate := ctx.Query("endDate") | |||
| startTime, _ := time.ParseInLocation("2006-01-02", startDate, time.Local) | |||
| endTime, _ := time.ParseInLocation("2006-01-02", endDate, time.Local) | |||
| result, count := models.QueryMetrics(startTime.Unix(), endTime.Unix()) | |||
| mapInterface := make(map[string]interface{}) | |||
| mapInterface["data"] = result | |||
| mapInterface["count"] = count | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| func queryMetrics(ctx *context.Context, tableName string, startTime time.Time, endTime time.Time) { | |||
| IsReturnFile := ctx.QueryBool("IsReturnFile") | |||
| var count int64 | |||
| result := make([]*models.UserMetrics, 0) | |||
| if tableName == "public.user_business_analysis_current_year" { | |||
| result = models.QueryMetricsForYear(startTime.Unix(), endTime.Unix()) | |||
| count = int64(len(result)) | |||
| } else if tableName == "public.user_business_analysis_all" { | |||
| result = models.QueryMetricsForAll(startTime.Unix(), endTime.Unix()) | |||
| count = int64(len(result)) | |||
| } else { | |||
| result, count = models.QueryMetricsPage(startTime.Unix(), endTime.Unix()) | |||
| } | |||
| if IsReturnFile { | |||
| //writer exec file. | |||
| xlsx := excelize.NewFile() | |||
| sheetName := ctx.Tr("user.metrics.sheetname") | |||
| index := xlsx.NewSheet(sheetName) | |||
| xlsx.DeleteSheet("Sheet1") | |||
| dataHeader := getUserMetricsExcelHeader(ctx) | |||
| for k, v := range dataHeader { | |||
| //设置单元格的值 | |||
| xlsx.SetCellValue(sheetName, k, v) | |||
| } | |||
| row := 1 | |||
| log.Info("return count=" + fmt.Sprint(count)) | |||
| for _, userRecord := range result { | |||
| row++ | |||
| writeUserMetricsExcel(row, xlsx, sheetName, userRecord) | |||
| } | |||
| //设置默认打开的表单 | |||
| xlsx.SetActiveSheet(index) | |||
| filename := sheetName + "_" + ctx.Tr("user.static."+tableName) + ".xlsx" | |||
| if tableName == "" { | |||
| filename = sheetName + "_" + getTimeFileName(startTime) + "_" + getTimeFileName(endTime) + ".xlsx" | |||
| } | |||
| ctx.Resp.Header().Set("Content-Disposition", "attachment; filename="+url.QueryEscape(filename)) | |||
| ctx.Resp.Header().Set("Content-Type", "application/octet-stream") | |||
| if _, err := xlsx.WriteTo(ctx.Resp); err != nil { | |||
| log.Info("writer exel error." + err.Error()) | |||
| } | |||
| } else { | |||
| mapInterface := make(map[string]interface{}) | |||
| mapInterface["data"] = result | |||
| mapInterface["count"] = count | |||
| if tableName == "public.user_business_analysis_yesterday" { | |||
| mapInterface["datarecordbegintime"] = setting.RadarMap.GrowthBeginTime | |||
| if len(result) > 0 { | |||
| dateTime := time.Unix(result[0].CountDate, 0) | |||
| mapInterface["lastUpdatedTime"] = dateTime.Format("2006-01-02 15:04:05") | |||
| } else { | |||
| mapInterface["lastUpdatedTime"] = "" | |||
| } | |||
| } | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| } | |||
| } | |||
| func getTimeFileName(t time.Time) string { | |||
| t = t.Local() | |||
| return t.Format("20060102") | |||
| } | |||
| func QueryRankingList(ctx *context.Context) { | |||
| @@ -224,34 +330,103 @@ func QueryRankingList(ctx *context.Context) { | |||
| ctx.JSON(http.StatusOK, mapInterface) | |||
| } | |||
| func QueryUserMetricsCurrentMonth(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| queryMetrics(ctx, "public.user_business_analysis_current_month", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticCurrentMonth(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_current_month", new(models.UserBusinessAnalysisCurrentMonth)) | |||
| } | |||
| func getStartTime(pageStartTime time.Time) time.Time { | |||
| t, _ := time.ParseInLocation("2006-01-02", setting.RadarMap.GrowthBeginTime, time.Local) | |||
| t = t.UTC() | |||
| if pageStartTime.Before(t) { | |||
| pageStartTime = t | |||
| } | |||
| return pageStartTime | |||
| } | |||
| func QueryUserMetricsCurrentWeek(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| offset := int(time.Monday - currentTimeNow.Weekday()) | |||
| if offset > 0 { | |||
| offset = -6 | |||
| } | |||
| pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| queryMetrics(ctx, "public.user_business_analysis_current_week", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticCurrentWeek(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_current_week", new(models.UserBusinessAnalysisCurrentWeek)) | |||
| } | |||
| func QueryUserMetricsCurrentYear(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| pageStartTime := time.Date(currentTimeNow.Year(), 1, 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| queryMetrics(ctx, "public.user_business_analysis_current_year", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticCurrentYear(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_current_year", new(models.UserBusinessAnalysisCurrentYear)) | |||
| } | |||
| func QueryUserMetricsLast30Day(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, -30) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| queryMetrics(ctx, "public.user_business_analysis_last30_day", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticLast30Day(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_last30_day", new(models.UserBusinessAnalysisLast30Day)) | |||
| } | |||
| func QueryUserMetricsLastMonth(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| thisMonth := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 0, 0, 0, 0, currentTimeNow.Location()) | |||
| pageStartTime := thisMonth.AddDate(0, -1, 0) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), 1, 23, 59, 59, 0, currentTimeNow.Location()).AddDate(0, 0, -1) | |||
| queryMetrics(ctx, "public.user_business_analysis_last_month", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticLastMonth(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_last_month", new(models.UserBusinessAnalysisLastMonth)) | |||
| } | |||
| func QueryUserMetricsYesterday(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| pageStartTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 0, 0, 0, 0, time.Local) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| queryMetrics(ctx, "public.user_business_analysis_yesterday", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticYesterday(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_yesterday", new(models.UserBusinessAnalysisYesterday)) | |||
| } | |||
| func QueryUserMetricsAll(ctx *context.Context) { | |||
| currentTimeNow := time.Now() | |||
| pageStartTime := time.Date(2022, 4, 5, 0, 0, 0, 0, currentTimeNow.Location()) | |||
| pageStartTime = getStartTime(pageStartTime) | |||
| pageEndTime := time.Date(currentTimeNow.Year(), currentTimeNow.Month(), currentTimeNow.Day(), 23, 59, 59, 0, currentTimeNow.Location()) | |||
| queryMetrics(ctx, "public.user_business_analysis_all", pageStartTime, pageEndTime) | |||
| } | |||
| func QueryUserStaticAll(ctx *context.Context) { | |||
| queryUserDataPage(ctx, "public.user_business_analysis_all", new(models.UserBusinessAnalysisAll)) | |||
| } | |||
| func QueryUserMetricDataPage(ctx *context.Context) { | |||
| startDate := ctx.Query("startDate") | |||
| endDate := ctx.Query("endDate") | |||
| startTime, _ := time.ParseInLocation("2006-01-02", startDate, time.Local) | |||
| startTime = startTime.UTC() | |||
| endTime, _ := time.ParseInLocation("2006-01-02", endDate, time.Local) | |||
| startTime = getStartTime(startTime) | |||
| queryMetrics(ctx, "", startTime, endTime) | |||
| } | |||
| func QueryUserStaticDataPage(ctx *context.Context) { | |||
| startDate := ctx.Query("startDate") | |||
| endDate := ctx.Query("endDate") | |||
| @@ -608,6 +608,11 @@ func getContributorInfo(contributorInfos []*ContributorInfo, email string) *Cont | |||
| // Home render repository home page | |||
| func Home(ctx *context.Context) { | |||
| if ctx.Repo.CanEnableEditor() { | |||
| ctx.Data["CanEditFile"] = true | |||
| } else { | |||
| ctx.Data["CanEditFile"] = false | |||
| } | |||
| if len(ctx.Repo.Units) > 0 { | |||
| //get repo contributors info | |||
| contributors, err := git.GetContributors(ctx.Repo.Repository.RepoPath(), ctx.Repo.BranchName) | |||
| @@ -0,0 +1,32 @@ | |||
| package response | |||
| const ( | |||
| RESPONSE_CODE_SUCCESS = 0 | |||
| RESPONSE_MSG_SUCCESS = "ok" | |||
| RESPONSE_CODE_ERROR_DEFAULT = 99 | |||
| ) | |||
| type AiforgeResponse struct { | |||
| Code int | |||
| Msg string | |||
| Data interface{} | |||
| } | |||
| func Success() *AiforgeResponse { | |||
| return &AiforgeResponse{Code: RESPONSE_CODE_SUCCESS, Msg: RESPONSE_MSG_SUCCESS} | |||
| } | |||
| func Error(code int, msg string) *AiforgeResponse { | |||
| return &AiforgeResponse{Code: code, Msg: msg} | |||
| } | |||
| func ServerError(msg string) *AiforgeResponse { | |||
| return &AiforgeResponse{Code: RESPONSE_CODE_ERROR_DEFAULT, Msg: msg} | |||
| } | |||
| func SuccessWithData(data interface{}) *AiforgeResponse { | |||
| return &AiforgeResponse{Code: RESPONSE_CODE_ERROR_DEFAULT, Msg: RESPONSE_MSG_SUCCESS, Data: data} | |||
| } | |||
| func ErrorWithData(code int, msg string, data interface{}) *AiforgeResponse { | |||
| return &AiforgeResponse{Code: code, Msg: msg, Data: data} | |||
| } | |||
| @@ -325,6 +325,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/action/notification", routers.ActionNotification) | |||
| m.Get("/recommend/org", routers.RecommendOrgFromPromote) | |||
| m.Get("/recommend/repo", routers.RecommendRepoFromPromote) | |||
| m.Get("/recommend/userrank/:index", routers.GetUserRankFromPromote) | |||
| m.Get("/recommend/imageinfo", routers.GetImageInfoFromPromote) | |||
| m.Post("/all/search/", routers.Search) | |||
| m.Get("/all/search/", routers.EmptySearch) | |||
| m.Get("/all/dosearch/", routers.SearchApi) | |||
| @@ -344,6 +346,13 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Get("/code", routers.ExploreCode) | |||
| m.Get("/images", routers.ExploreImages) | |||
| m.Get("/data_analysis", routers.ExploreDataAnalysis) | |||
| m.Get("/data_analysis/UserTrend", routers.ExploreDataAnalysisUserTrend) | |||
| m.Get("/data_analysis/UserAnalysis", routers.ExploreDataAnalysisUserAnalysis) | |||
| m.Get("/data_analysis/ProAnalysis", routers.ExploreDataAnalysisProAnalysis) | |||
| m.Get("/data_analysis/ProTrend", routers.ExploreDataAnalysisProTrend) | |||
| m.Get("/data_analysis/Overview", routers.ExploreDataAnalysisOverview) | |||
| m.Get("/data_analysis/BrainAnalysis", routers.ExploreDataAnalysisBrainAnalysis) | |||
| }, ignSignIn) | |||
| m.Combo("/install", routers.InstallInit).Get(routers.Install). | |||
| Post(bindIgnErr(auth.InstallForm{}), routers.InstallPost) | |||
| @@ -933,6 +942,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| m.Combo("/_upload/*", repo.MustBeAbleToUpload). | |||
| Get(repo.UploadFile). | |||
| Post(bindIgnErr(auth.UploadRepoFileForm{}), repo.UploadFilePost) | |||
| m.Post("/_rename/*", bindIgnErr(auth.RenameRepoFileForm{}), repo.RenameFilePost) | |||
| }, context.RepoRefByType(context.RepoRefBranch), repo.MustBeEditable) | |||
| m.Group("", func() { | |||
| m.Post("/upload-file", repo.UploadFileToServer) | |||
| @@ -778,8 +778,8 @@ func Cloudbrains(ctx *context.Context) { | |||
| var jobTypes []string | |||
| jobTypeNot := false | |||
| if jobType == string(models.JobTypeDebug) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeSnn4imagenet), string(models.JobTypeBrainScore), string(models.JobTypeDebug)) | |||
| if jobType == string(models.JobTypeBenchmark) { | |||
| jobTypes = append(jobTypes, string(models.JobTypeBenchmark), string(models.JobTypeBrainScore), string(models.JobTypeSnn4imagenet)) | |||
| } else if jobType != "all" && jobType != "" { | |||
| jobTypes = append(jobTypes, jobType) | |||
| } | |||
| @@ -19,6 +19,8 @@ import ( | |||
| pull_service "code.gitea.io/gitea/services/pull" | |||
| ) | |||
| const SHELL_FLAG_ON = 1 | |||
| // CreateRepository creates a repository for the user/organization. | |||
| func CreateRepository(doer, owner *models.User, opts models.CreateRepoOptions) (*models.Repository, error) { | |||
| repo, err := repo_module.CreateRepository(doer, owner, opts) | |||
| @@ -1,6 +1,6 @@ | |||
| {{template "base/head" .}} | |||
| <!-- 弹窗 --> | |||
| <div id="mask"> | |||
| <!-- 弹窗 --> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| @@ -12,20 +12,26 @@ | |||
| <!-- 提示框 --> | |||
| <div class="alert"></div> | |||
| <div class="admin user"> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" data-debug-again="{{$.i18n.Tr "repo.debug_again"}}"></div> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" | |||
| data-debug-again="{{$.i18n.Tr "repo.debug_again"}}" | |||
| data-all-task="{{.i18n.Tr "admin.cloudbrain.all_task_types"}}" | |||
| data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | |||
| data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | |||
| {{template "admin/navbar" .}} | |||
| <div class="ui container" style="width: 80%;"> | |||
| {{template "base/alert" .}} | |||
| <div class="ui grid" > | |||
| <div class="ui grid"> | |||
| <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||
| {{template "admin/cloudbrain/search" .}} | |||
| <div class="ui six wide column right aligned" style="margin: 1rem 0;"> | |||
| <a class="ui compact blue basic icon button" style="box-shadow: none !important; padding: 0.8em;" href="/admin/cloudbrains/download"><i class="ri-download-line middle aligned icon"></i>{{.i18n.Tr "admin.cloudbrain.download_report"}}</a> | |||
| <a class="ui compact blue basic icon button" style="box-shadow: none !important; padding: 0.8em;" | |||
| href="/admin/cloudbrains/download"><i | |||
| class="ri-download-line middle aligned icon"></i>{{.i18n.Tr "admin.cloudbrain.download_report"}}</a> | |||
| </div> | |||
| <div class="ui sixteen wide column"> | |||
| <!-- 任务展示 --> | |||
| <div class="dataset list"> | |||
| <!-- 表头 --> | |||
| <!-- 表头 --> | |||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
| <div class="row"> | |||
| <div class="two wide column nowrap"> | |||
| @@ -38,13 +44,13 @@ | |||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||
| </div> | |||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center nowrap"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center nowrap"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| </div> | |||
| <div class="one wide column text center nowrap"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
| @@ -73,21 +79,40 @@ | |||
| {{end}} | |||
| <!-- {{$JobID}} --> | |||
| <div class="two wide column nowrap"> | |||
| {{if or (eq .JobType "DEBUG") (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/train-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts{{end}}/train-job/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| @@ -96,50 +121,68 @@ | |||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <div class="two wide column text center nowrap" | |||
| style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}/modelarts/train-job{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | |||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| <span style="font-size: 12px;" | |||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center nowrap"> | |||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| <span style="font-size: 12px;" | |||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center nowrap"> | |||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| <span | |||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 创建者 --> | |||
| <div class="one wide column text center nowrap"> | |||
| {{if .User.Name}} | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | |||
| class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| {{else}} | |||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| <a title="Ghost"><img class="ui avatar image" | |||
| src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 项目 --> | |||
| <div class="two wide column text center nowrap"> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | |||
| title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||
| </div> | |||
| <!-- 云脑侧名称 --> | |||
| <div class="two wide column text center nowrap" style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <div class="two wide column text center nowrap" | |||
| style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <span class="fitted" title="{{.JobName}}">{{.JobName}}</span> | |||
| </div> | |||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE"}} | |||
| {{if eq .JobType "DEBUG"}} | |||
| <div class="ui compact buttons"> | |||
| <form id="debugAgainForm-{{$JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" | |||
| class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' | |||
| data-jobid="{{$JobID}}" | |||
| data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| <a id="ai-debug-{{$JobID}}" | |||
| class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' | |||
| data-jobid="{{$JobID}}" | |||
| data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -149,22 +192,33 @@ | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| {{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}} | |||
| <form id="stopForm-{{$JobID}}" style="margin-left:-1px;"> | |||
| <form id="stopForm-{{$JobID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop' data-jobid="{{$JobID}}"> | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
| class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING"}}disabled {{else}} blue {{end}}button' | |||
| data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop' | |||
| data-jobid="{{$JobID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </form> | |||
| {{else}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED"}}disabled {{else}} blue {{end}}button" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/train-job{{else}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}{{end}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
| class="ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED"}}disabled {{else}} blue {{end}}button" | |||
| data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/train-job{{else}}/modelarts/{{if eq .JobType "INFERENCE"}}inference-job{{else}}train-job{{end}}{{end}}" | |||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}/train-job{{end}}/{{$JobID}}/del?isadminpage=true' method="post"> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" | |||
| action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}/train-job{{end}}/{{$JobID}}/del?isadminpage=true' | |||
| method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?isadminpage=true" data-version="" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | |||
| data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?isadminpage=true" | |||
| data-version="" class="ui basic ai_delete blue button" | |||
| style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| @@ -184,19 +238,23 @@ | |||
| <div class="two wide column nowrap"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| @@ -205,29 +263,38 @@ | |||
| <span style="font-size: 12px;">{{.JobType}} </span> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <div class="two wide column text center nowrap" | |||
| style="padding-left: 2.2rem !important; width: 10% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" | |||
| data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center nowrap" style="width: 10% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| <span style="font-size: 12px;" | |||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center nowrap"> | |||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| <span style="font-size: 12px;" | |||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center nowrap"> | |||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| <span | |||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 创建者 --> | |||
| <div class="one wide column text center nowrap"> | |||
| {{if .User.Name}} | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | |||
| class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| {{else}} | |||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| <a title="Ghost"><img class="ui avatar image" | |||
| src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 项目 --> | |||
| @@ -235,7 +302,8 @@ | |||
| <a href="" title="">--</a> | |||
| </div> | |||
| <!-- 云脑侧名称 --> | |||
| <div class="two wide column text center nowrap" style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <div class="two wide column text center nowrap" | |||
| style="overflow: hidden;text-overflow:ellipsis;"> | |||
| <span class="fitted">{{.JobName}}</span> | |||
| </div> | |||
| <div class="two wide column text center nowrap" style="width: 17.5%!important;"> | |||
| @@ -244,11 +312,12 @@ | |||
| <form id="debugAgainForm-{{$JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" | |||
| class='ui basic disabled button'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic disabled button'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -257,14 +326,17 @@ | |||
| {{end}} | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic disabled button" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
| class="ui basic disabled button" data-jobid="{{$JobID}}" | |||
| data-version="{{.VersionName}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </div> | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='' method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | |||
| class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| @@ -276,14 +348,9 @@ | |||
| {{end}} | |||
| <div id="app" style="margin-top: 2rem;"> | |||
| <div class="center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-sizes="[10]" | |||
| :page-size="10" | |||
| layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| <el-pagination background @current-change="handleCurrentChange" :current-page="page" | |||
| :page-sizes="[10]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| @@ -314,17 +381,4 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| function getParams(){ | |||
| const params = new URLSearchParams(window.location.search) | |||
| let jobType = !params.get('jobType')? '{{.i18n.Tr "admin.cloudbrain.all_task_types"}}' : params.get('jobType') | |||
| let listType = !params.get('listType')? '{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}' : params.get('listType') | |||
| let jobStatus = !params.get('jobStatus')? '{{.i18n.Tr "admin.cloudbrain.all_status"}}' : params.get('jobStatus').toUpperCase() | |||
| const dropdownValueArray = [jobType,listType,jobStatus] | |||
| $('#adminCloud .default.text ').each(function(index,e){ | |||
| $(e).text(dropdownValueArray[index]) | |||
| }) | |||
| } | |||
| getParams() | |||
| </script> | |||
| {{template "base/footer" .}} | |||
| @@ -16,8 +16,8 @@ | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=TRAIN&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="TRAIN">TRAIN</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=INFERENCE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="INFERENCE">INFERENCE</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BENCHMARK&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">BENCHMARK</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4IMAGENET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">SNN4IMAGENET</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BRAINSCORE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">BRAINSCORE</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4IMAGENET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="SNN4IMAGENET">SNN4IMAGENET</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BRAINSCORE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BRAINSCORE">BRAINSCORE</a> | |||
| </div> | |||
| </div> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| @@ -18,7 +18,7 @@ | |||
| <div class="ui container" style="width: 80%;"> | |||
| <div class="ui grid"> | |||
| <div class="row"> | |||
| <div class="ui {{if $.PageIsUserCloudBrain}}sixteen{{else}}six{{end}} wide column" style="margin: 1rem 0;" id="adminCloud"> | |||
| <div class="ui {{if $.PageIsUserCloudBrain}}sixteen{{else}}six{{end}} wide column" style="margin: 1rem 0;" id="userCloud"> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| <div class="default text" style="color: rgba(0,0,0,.87);">{{.i18n.Tr "admin.cloudbrain.all_task_types"}}</div> | |||
| <i class="dropdown icon"></i> | |||
| @@ -28,8 +28,8 @@ | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=TRAIN&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="TRAIN">{{.i18n.Tr "cloudbrain.TRAIN"}}</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=INFERENCE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="INFERENCE">{{.i18n.Tr "cloudbrain.INFERENCE"}}</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BENCHMARK&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">{{.i18n.Tr "cloudbrain.BENCHMARK"}}</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4IMAGENET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">{{.i18n.Tr "cloudbrain.SNN4IMAGENET"}}</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BRAINSCORE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">{{.i18n.Tr "cloudbrain.BRAINSCORE"}}</a> | |||
| <!-- <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=SNN4IMAGENET&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">{{.i18n.Tr "cloudbrain.SNN4IMAGENET"}}</a> | |||
| <a class="item" href="{{$.Link}}?q={{$.Keyword}}&jobType=BRAINSCORE&listType={{$.ListType}}&jobStatus={{$.JobStatus}}" data-value="BENCHMARK">{{.i18n.Tr "cloudbrain.BRAINSCORE"}}</a> --> | |||
| </div> | |||
| </div> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| @@ -1,14 +1,17 @@ | |||
| <div class="dataset-repolink" id="dataset-repolink-init" style="display: none;" data-repolink="{{.RepoLink}}" data-cloudranin-type="{{.cloudbraintype}}"></div> | |||
| <div class="inline required unite min_title field" id="dataset-base" style="margin-bottom: 0 !important;"> | |||
| {{if .newInference}} | |||
| <label style="font-weight: normal;">{{.i18n.Tr "dataset.dataset"}}</label> | |||
| {{if or (.benchmarkMode) (.newInference)}} | |||
| <label style="font-weight: normal;">{{if .benchmarkMode}}{{.i18n.Tr "repo.model_manager"}}</label><span> </span>{{else}}{{.i18n.Tr "dataset.dataset"}}</label> {{end}} | |||
| {{else}} | |||
| <label style="font-weight: normal;">{{.i18n.Tr "dataset.dataset"}}</label> | |||
| {{end}} | |||
| <input type="hidden" name="attachment" :value="dataset_uuid"> | |||
| <input class="disabled" type="text" :value="dataset_name" required onfocus="this.blur();" style="width: 48.5%;"> | |||
| <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;"> {{.i18n.Tr "dataset.select_dataset"}}</el-button> | |||
| <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;"> {{if .benchmarkMode}}{{.i18n.Tr "repo.modelarts.infer_job.select_model"}}{{else}}{{.i18n.Tr "dataset.select_dataset"}}{{end}}</el-button> | |||
| {{if .benchmarkMode}} | |||
| <span class="tooltips" style="display: block;padding-left: 0.5rem;">说明:先使用数据集功能上传模型,然后从数据集列表选模型。</span> | |||
| {{end}} | |||
| <el-dialog | |||
| title="{{.i18n.Tr "dataset.select_dataset"}}" | |||
| :visible.sync="dialogVisible" | |||
| @@ -44,7 +47,7 @@ | |||
| </div> | |||
| </div> | |||
| {{if not .benchmarkMode}} | |||
| </el-tab-pane> | |||
| <el-tab-pane label="{{.i18n.Tr "dataset.owner_dataset"}}" name="second"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(dataset,index) in myDataset" :key="index"> | |||
| @@ -121,6 +124,7 @@ | |||
| </div> | |||
| </el-tab-pane> | |||
| {{end}} | |||
| </el-tabs> | |||
| <div class="center"> | |||
| <el-pagination | |||
| @@ -1,15 +1,21 @@ | |||
| {{template "base/head_fluid" .}} | |||
| <input id="url_params" type="hidden" value={{.url_params}}/> | |||
| <div id="data_analysis" style="height: 100%;"> | |||
| </div> | |||
| {{template "base/footer_fluid" .}} | |||
| <!-- <script> | |||
| localStorage.setItem("dataAnalysisURL","{{.url_params}}") | |||
| </script> --> | |||
| <style> | |||
| .full.height { | |||
| display: flex; | |||
| flex-flow: column wrap; | |||
| padding-bottom:0px; | |||
| /* flex-grow: 1; */ | |||
| padding-bottom: 53px; | |||
| /* padding-bottom: 53px; */ | |||
| } | |||
| </style> | |||
| @@ -1,4 +1,4 @@ | |||
| <a href="https://openi.org.cn/html/2020/qimengxingdong_0813/450.html" target="_blank"><img class="ui mini image" src="/img/banner-qimen-4X3.jpg" style="width:100%;"></a> | |||
| <a href="https://openi.org.cn/index.php?m=content&c=index&a=lists&catid=208" target="_blank"><img class="ui mini image" src="https://openi.org.cn/uploadfile/2022/0507/e8bdd42ed598f12.jpg" style="width:100%;"></a> | |||
| <div class="ui secondary pointing menu"> | |||
| <div class="active item"> | |||
| @@ -36,6 +36,20 @@ | |||
| <!--组织--> | |||
| <div class="ui container homeorg"> | |||
| <div class="ui stackable grid"> | |||
| <div class="sixteen wide tablet four wide computer column homeorg-tit"> | |||
| <h2>{{.page_recommend_activity}}</h2> | |||
| <p><span class="ui text grey">{{.page_recommend_activity_desc}}</p> | |||
| </div> | |||
| <div class="sixteen wide tablet twelve wide computer column"> | |||
| <div class="event-list"> | |||
| <div class="swiper-wrapper" id="recommendactivity"> | |||
| </div> | |||
| <div class="swiper-pagination"></div> | |||
| </div> | |||
| </div> | |||
| <div class="sixteen wide tablet four wide computer column homeorg-tit"> | |||
| <h2>{{.page_recommend_org}}</h2> | |||
| <p><span class="ui text grey">{{.page_recommend_org_desc}} </span><a href="{{.RecommendURL}}">{{.page_recommend_org_commit}}</a></p> | |||
| @@ -15,7 +15,7 @@ | |||
| <span class="help">{{.i18n.Tr "org.org_name_helper"}}</span> | |||
| </div> | |||
| <div class="inline field {{if .Err_OrgVisibility}}error{{end}}"> | |||
| <!-- <div class="inline field {{if .Err_OrgVisibility}}error{{end}}"> | |||
| <span class="inline required field"><label for="visibility">{{.i18n.Tr "org.settings.visibility"}}</label></span> | |||
| <div class="inline-grouped-list"> | |||
| <div class="ui radio checkbox"> | |||
| @@ -31,7 +31,7 @@ | |||
| <label>{{.i18n.Tr "org.settings.visibility.private"}}</label> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> --> | |||
| <div class="inline field" id="permission_box"> | |||
| <label>{{.i18n.Tr "org.settings.permission"}}</label> | |||
| @@ -39,7 +39,6 @@ | |||
| </a> | |||
| {{end}} | |||
| {{end}} | |||
| {{if .OrgTopics}} | |||
| <a class=" tag_key ui small tag_lable topic omit icon_a" onclick="isUnfold()" id="icon_btn" > | |||
| <i class="ri-arrow-down-s-line" style="display:inline-block;vertical-align:top"></i> | |||
| @@ -168,7 +167,10 @@ | |||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | |||
| } | |||
| } | |||
| isShowIconBtn() | |||
| iscontinueStatus() | |||
| if ({{.OrgTopics}}.length>0){ | |||
| isShowIconBtn() | |||
| iscontinueStatus() | |||
| } | |||
| </script> | |||
| @@ -43,13 +43,13 @@ | |||
| </div> | |||
| </div> | |||
| <div class="field"> | |||
| <div class="ui radio checkbox"> | |||
| <div class="ui radio disabled checkbox"> | |||
| <input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="1" {{if eq .CurrentVisibility 1}}checked{{end}}/> | |||
| <label>{{.i18n.Tr "org.settings.visibility.limited"}}</label> | |||
| </div> | |||
| </div> | |||
| <div class="field"> | |||
| <div class="ui radio checkbox"> | |||
| <div class="ui radio disabled checkbox"> | |||
| <input class="hidden enable-system-radio" tabindex="0" name="visibility" type="radio" value="2" {{if eq .CurrentVisibility 2}}checked{{end}}/> | |||
| <label>{{.i18n.Tr "org.settings.visibility.private"}}</label> | |||
| </div> | |||
| @@ -2,9 +2,6 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .fontsize14{ | |||
| font-size: 14px; | |||
| } | |||
| .padding0{ | |||
| padding: 0 !important; | |||
| } | |||
| @@ -69,28 +66,31 @@ | |||
| <!-- 表头 --> | |||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
| <div class="row"> | |||
| <div class="three wide column padding0"> | |||
| <div class="three wide column padding0" style="width: 18% !important;"> | |||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.status"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <span>{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <span>{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 8.5% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <div class="one wide column text center padding0" style="width: 8% !important;"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 8% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| </div> | |||
| <div class="one wide column text center padding0"> | |||
| <div class="one wide column text center padding0" style="width: 6% !important;"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_creator"}}</span> | |||
| </div> | |||
| <div class="three wide column text center padding0"> | |||
| <div class="three wide column text center padding0" style="width: 20% !important;"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | |||
| </div> | |||
| </div> | |||
| @@ -101,36 +101,39 @@ | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| <div class="three wide column padding0"> | |||
| <div class="three wide column padding0" style="width: 18% !important;"> | |||
| <a class="title" href="{{$.Link}}/{{.Cloudbrain.ID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column padding0" style="padding-left: 2.2rem !important;"> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| {{.BenchmarkType}} | |||
| </div> | |||
| <div class="two wide column text center padding0" style="width: 10.5% !important;"> | |||
| <a style="font-size: 12px;" href="{{.BenchmarkTypeRankLink}}" target="_blank"> | |||
| {{.BenchmarkTypeName}} | |||
| {{.BenchmarkTypeName}} | |||
| </a> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 8.5% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center padding0"> | |||
| <div class="one wide column text center padding0" style="width: 8% !important;"> | |||
| <span style="font-size: 12px;" id="duration-{{.Cloudbrain.ID}}">{{.TrainJobDuration}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="two wide column text center padding0"> | |||
| <div class="two wide column text center padding0" style="width: 8% !important;"> | |||
| <span style="font-size: 12px;">{{.ComputeResource}}</span> | |||
| </div> | |||
| <!-- 创建者 --> | |||
| <div class="one wide column text center padding0"> | |||
| <div class="one wide column text center padding0" style="width: 6% !important;"> | |||
| {{if .User.Name}} | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| {{else}} | |||
| @@ -138,7 +141,7 @@ | |||
| {{end}} | |||
| </div> | |||
| <div class="three wide column text center padding0"> | |||
| <div class="three wide column text center padding0" style="width: 20% !important;"> | |||
| <div class="ui compact buttons" > | |||
| <!-- 停止任务 --> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| @@ -154,10 +157,11 @@ | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| {{if eq .JobType "BENCHMARK"}} | |||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||
| {{$.i18n.Tr "repo.score"}} | |||
| </a> | |||
| {{end}} | |||
| <!-- 删除任务 --> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/benchmark{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <input type="hidden" name="debugListType" value="all"> | |||
| @@ -226,4 +230,4 @@ | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| {{template "base/footer" .}} | |||
| @@ -1,70 +1,46 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .unite { | |||
| font-family: SourceHanSansSC-medium !important; | |||
| color: rgba(16, 16, 16, 100) !important; | |||
| } | |||
| .title { | |||
| font-size: 16px !important; | |||
| padding-left: 3rem !important; | |||
| } | |||
| .min_title { | |||
| font-size: 14px !important; | |||
| padding-left: 6rem !important; | |||
| margin-bottom: 2rem !important; | |||
| .unite{ | |||
| font-family: SourceHanSansSC-medium !important; | |||
| color: rgba(16, 16, 16, 100) !important; | |||
| } | |||
| .title{ | |||
| font-size: 16px !important; | |||
| padding-left: 3rem !important; | |||
| } | |||
| .min_title{ | |||
| font-size: 14px !important; | |||
| padding-left: 6rem !important; | |||
| margin-bottom: 2rem !important; | |||
| } | |||
| .width{ | |||
| width:100% !important; | |||
| } | |||
| .width80{ | |||
| width: 80.7% !important; | |||
| margin-left: 10px; | |||
| } | |||
| .width85{ | |||
| width: 85% !important; | |||
| margin-left: 4.5rem !important; | |||
| } | |||
| .width81{ | |||
| margin-left: 1.5rem; | |||
| width: 81% !important; | |||
| } | |||
| .add{font-size: 18px; | |||
| padding: 0.5rem; | |||
| border: 1px solid rgba(187, 187, 187, 100); | |||
| border-radius: 0px 5px 5px 0px; | |||
| line-height: 21px; | |||
| text-align: center; | |||
| color: #C2C7CC; | |||
| } | |||
| .min{ | |||
| font-size: 18px; | |||
| padding: 0.5rem; | |||
| border: 1px solid rgba(187, 187, 187, 100); | |||
| border-radius: 5px 0px 0px 5px; | |||
| line-height: 21px; | |||
| text-align: center; | |||
| color: #C2C7CC; | |||
| } | |||
| .nowrapx { | |||
| white-space: nowrap !important; | |||
| } | |||
| } | |||
| .width81 { | |||
| margin-left: 1.5rem; | |||
| width: 81% !important; | |||
| } | |||
| .width48 { | |||
| width: 48.5% !important; | |||
| } | |||
| .nowrapx { | |||
| white-space: nowrap !important; | |||
| } | |||
| </style> | |||
| <!-- <div class="ui page dimmer"> | |||
| <div class="ui text loader">{{.i18n.Tr "loading"}}</div> | |||
| </div> --> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| <div class="rect3"></div> | |||
| <div class="rect4"></div> | |||
| <div class="rect5"></div> | |||
| </div> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| <div class="rect3"></div> | |||
| <div class="rect4"></div> | |||
| <div class="rect5"></div> | |||
| </div> | |||
| </div> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| @@ -74,168 +50,306 @@ | |||
| {{.i18n.Tr "repo.modelarts.evaluate_job.new_job"}} | |||
| </h4> | |||
| <div class="ui attached segment"> | |||
| <!-- equal width --> | |||
| <form class="ui form" action="{{.Link}}" method="post"> | |||
| <input type="hidden" name="benchmarkMode" value="{{.benchmarkMode}}"> | |||
| {{if eq .benchmarkMode "model"}} | |||
| <form class="ui form model_form" action="{{.Link}}?benchmarkMode=model" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="action" value="update"> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="254"> | |||
| </div> | |||
| <div class="unite min_title inline field"> | |||
| <label style="font-weight: normal;" for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} onchange="this.value=this.value.substring(0, 255)" onkeydown="this.value=this.value.substring(0, 255)" onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="item alogrithm_benchmark" | |||
| href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
| <a class="active item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||
| tabindex="3" autofocus required maxlength="254"> | |||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
| </div> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;" | |||
| for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}}</label> | |||
| <textarea style="width: 80%;" id="description" name="description" rows="3" required | |||
| maxlength="254" placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||
| onchange="this.value=this.value.substring(0, 255)" | |||
| onkeydown="this.value=this.value.substring(0, 255)" | |||
| onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| </div> | |||
| <div class="required unite min_title inline field"> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown width48" placeholder="选择GPU类型" | |||
| name="gpu_type"> | |||
| {{range .benchmark_gpu_types}} | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <div class="required unite min_title two inline fields "> | |||
| <div class="required ten wide field" style="width: 26.5% !important;"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||
| <select id="cloudbrain_job_type" class="ui search dropdown job_type" | |||
| placeholder="select {{.i18n.Tr "cloudbrain.task_type"}}" name="job_type"> | |||
| <option value="SNN4IMAGENET">SNN4IMAGENET</option> | |||
| <option value="BRAINSCORE">BRAINSCORE</option> | |||
| </select> | |||
| </div> | |||
| <div class="required six widde field" id="brainscore_child_type" | |||
| style="width: 15% !important;display: none;"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.brain_area"}}</label> | |||
| <select class="ui search dropdown" placeholder="select {{.i18n.Tr "cloudbrain.brain_area"}}" | |||
| name="benchmark_child_types_id"> | |||
| <option value="0">V1</option> | |||
| <option value="1">V2</option> | |||
| <option value="2">V4</option> | |||
| <option value="3">IT</option> | |||
| </select> | |||
| </div> | |||
| <span> | |||
| <i class="question circle icon link" | |||
| data-content={{.i18n.Tr "repo.modelarts.train_job.boot_file_helper"}} | |||
| data-position="right center" data-variation="mini"></i> | |||
| </span> | |||
| <a id="benchmark_model_example" href="https://git.openi.org.cn/BDIP/snn4imagenet" | |||
| target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| <div class="required unite inline min_title fields" style="width: 90%;"> | |||
| <div class="required eight wide field"> | |||
| <label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | |||
| <span> </span> | |||
| <select class="ui fluid selection search dropdown" id="benchmark_types_id" name="benchmark_types_id" > | |||
| {{range .benchmark_types}} | |||
| {{if eq .Id $.benchmarkTypeID}} | |||
| <option value="{{.Id}}" selected="true">{{.First}}</option> | |||
| {{else}} | |||
| <option value="{{.Id}}">{{.First}}</option> | |||
| {{end}} | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| {{template "custom/select_dataset_train" .}} | |||
| <div class="required unite min_title inline field" style="margin-top:2rem;"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
| name="resource_spec_id"> | |||
| {{range .benchmark_resource_specs}} | |||
| <option name="resource_spec_id" value="{{.Id}}"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}} | |||
| </option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="eight wide field" id="engine_name"> | |||
| <input type="hidden" id="benchmark_child_types_id_hidden" name="benchmark_child_types_id_hidden" value="{{.benchmark_child_types_id_hidden}}"> | |||
| <label style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_child_type"}}</label> | |||
| <select class="ui fluid selection dropdown nowrapx" id="benchmark_child_types_id" style='width: 100%;' name="benchmark_child_types_id"> | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <div class="inline unite min_title field"> | |||
| <button class="ui create_train_job green button"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| </div> | |||
| <div id="images-new-cb"> | |||
| </form> | |||
| {{else}} | |||
| <form class="ui form alogrithm_form" action="{{.Link}}?benchmarkMode=alogrithm" method="post"> | |||
| {{.CsrfTokenHtml}} | |||
| <input type="hidden" name="action" value="update"> | |||
| <input type="hidden" name="job_type" value="BENCHMARK"> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}}</label> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="active item alogrithm_benchmark" | |||
| href="{{.Link}}?benchmarkMode=alogrithm">{{.i18n.Tr "repo.cloudbrain.benchmark.algorithm"}}</a> | |||
| <a class="item model_benchmark" | |||
| href="{{.Link}}?benchmarkMode=model">{{.i18n.Tr "repo.cloudbrain.benchmark.model"}}</a> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.modelarts.train_job.job_name"}}</label> | |||
| <input style="width: 80%;" name="display_job_name" id="trainjob_job_name" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.job_name"}} value="{{.display_job_name}}" | |||
| tabindex="3" autofocus required maxlength="254"> | |||
| <span class="tooltips" style="display: block;">{{.i18n.Tr "cloudbrain.job_name_rule"}}</span> | |||
| </div> | |||
| <div class="unite min_title inline field"> | |||
| <label style="font-weight: normal;" | |||
| for="description">{{.i18n.Tr "repo.modelarts.train_job.description"}} </label> | |||
| <textarea style="width: 80%;" id="description" name="description" rows="3" maxlength="254" | |||
| placeholder={{.i18n.Tr "repo.modelarts.train_job.new_place"}} | |||
| onchange="this.value=this.value.substring(0, 255)" | |||
| onkeydown="this.value=this.value.substring(0, 255)" | |||
| onkeyup="this.value=this.value.substring(0, 255)">{{.description}}</textarea> | |||
| </div> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" | |||
| style='width:385px' name="gpu_type"> | |||
| {{range .benchmark_gpu_types}} | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="required unite inline min_title fields" style="width: 90%;"> | |||
| <div class="required eight wide field"> | |||
| <label | |||
| style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}}</label> | |||
| <span> </span> | |||
| <select class="ui fluid selection search dropdown" id="benchmark_types_id" | |||
| name="benchmark_types_id"> | |||
| {{range .benchmark_types}} | |||
| {{if eq .Id $.benchmarkTypeID}} | |||
| <option value="{{.Id}}" selected="true">{{.First}}</option> | |||
| {{else}} | |||
| <option value="{{.Id}}">{{.First}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="eight wide field" id="engine_name"> | |||
| <input type="hidden" id="benchmark_child_types_id_hidden" | |||
| name="benchmark_child_types_id_hidden" value="{{.benchmark_child_types_id_hidden}}"> | |||
| <label | |||
| style="font-weight: normal;white-space: nowrap;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_child_type"}}</label> | |||
| <select class="ui fluid selection dropdown nowrapx" id="benchmark_child_types_id" | |||
| style='width: 100%;' name="benchmark_child_types_id"> | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| <div class="required unite min_title inline field"> | |||
| <div class="required unite min_title inline field"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="resource_spec_id"> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
| name="resource_spec_id"> | |||
| {{range .benchmark_resource_specs}} | |||
| <option name="resource_spec_id" value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||
| <option name="resource_spec_id" value="{{.Id}}"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}} | |||
| </option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| </div> | |||
| <div class="inline unite min_title field required"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" value="train.py" tabindex="3" autofocus required maxlength="254" > | |||
| <a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</a> | |||
| </div> | |||
| <div class="inline unite min_title field required"> | |||
| <label | |||
| style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="train_file" id="train_file" | |||
| value="train.py" tabindex="3" autofocus required maxlength="254"> | |||
| <a id="train_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" | |||
| target="_blank">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}}</a> | |||
| </div> | |||
| <div class="inline unite min_title field required"> | |||
| <label style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" tabindex="3" autofocus required maxlength="254" > | |||
| <a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| <div class="inline unite min_title field required"> | |||
| <label | |||
| style="font-weight: normal;">{{.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}}</label> | |||
| <input disabled="disabled" style="width: 33.5%;" name="test_file" id="test_file" value="test.py" | |||
| tabindex="3" autofocus required maxlength="254"> | |||
| <a id="test_href_id" href="https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark" | |||
| target="_blank">{{.i18n.Tr "cloudbrain.view_sample"}}</a> | |||
| </div> | |||
| <div class="inline unite min_title field"> | |||
| <button class="ui create_train_job green button"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| <div class="inline unite min_title field"> | |||
| <button class="ui create_train_job green button"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button" href="/">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| </div> | |||
| <!-- 模态框 --> | |||
| </form> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| let repolink = {{.RepoLink}} | |||
| let repolink = {{.RepoLink }} | |||
| let url_href = window.location.pathname.split('create')[0] | |||
| $(".ui.button").attr('href',url_href) | |||
| $(".ui.button").attr('href', url_href) | |||
| $('.menu .item') | |||
| .tab(); | |||
| $('#benchmark_types_id').change(function(){ | |||
| $('#benchmark_types_id').change(function () { | |||
| setChildType(); | |||
| }) | |||
| function setChildType(){ | |||
| $(document).ready(() => { | |||
| $('.ui.search.dropdown.job_type').dropdown({ | |||
| onChange: function (value, text, $selectedItem) { | |||
| console.log(value, text) | |||
| if (value === "BRAINSCORE") { | |||
| $('#brainscore_child_type').css('display', 'block') | |||
| $('#benchmark_model_example').attr('href', 'https://git.openi.org.cn/BDIP/similarity2brain_ann') | |||
| } else { | |||
| $('#brainscore_child_type').css('display', 'none') | |||
| $('#benchmark_model_example').attr('href', 'https://git.openi.org.cn/BDIP/snn4imagenet') | |||
| } | |||
| } | |||
| }) | |||
| }) | |||
| function setChildType() { | |||
| let type_id = $('#benchmark_types_id').val(); | |||
| if(type_id == 3){ | |||
| $('#train_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark'); | |||
| $('#test_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark'); | |||
| }else{ | |||
| $('#train_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark'); | |||
| $('#test_href_id').attr('href','https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark'); | |||
| if (type_id == 3) { | |||
| $('#train_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark'); | |||
| $('#test_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_MOT_benchmark'); | |||
| } else { | |||
| $('#train_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark'); | |||
| $('#test_href_id').attr('href', 'https://git.openi.org.cn/CV_benchmark/CV_reID_benchmark'); | |||
| } | |||
| let child_selected_id = $('#benchmark_child_types_id_hidden').val(); | |||
| let child_selected_id = $('#benchmark_child_types_id_hidden').val(); | |||
| $.get(`${repolink}/cloudbrain/benchmark/get_child_types?benchmark_type_id=${type_id}`, (data) => { | |||
| const n_length = data['child_types'].length | |||
| let html='' | |||
| for (let i=0;i<n_length;i++){ | |||
| if(child_selected_id == data['child_types'][i].id){ | |||
| let html = '' | |||
| for (let i = 0; i < n_length; i++) { | |||
| if (child_selected_id == data['child_types'][i].id) { | |||
| html += `<option value="${data['child_types'][i].id}" selected="true">${data['child_types'][i].value}</option>`; | |||
| }else{ | |||
| } else { | |||
| html += `<option value="${data['child_types'][i].id}">${data['child_types'][i].value}</option>`; | |||
| } | |||
| } | |||
| document.getElementById("benchmark_child_types_id").innerHTML=html; | |||
| document.getElementById("benchmark_child_types_id").innerHTML = html; | |||
| }) | |||
| } | |||
| document.onreadystatechange = function() { | |||
| document.onreadystatechange = function () { | |||
| if (document.readyState === "complete") { | |||
| setChildType(); | |||
| if ($('input[name=benchmarkMode]').val() === 'alogrithm' || $('input[name=benchmarkMode]').val() === '') { | |||
| setChildType(); | |||
| } | |||
| } | |||
| } | |||
| function validate(){ | |||
| function validate() { | |||
| $('.ui.form') | |||
| .form({ | |||
| on: 'blur', | |||
| inline:true, | |||
| fields: { | |||
| image:{ | |||
| identifier : 'image', | |||
| rules: [ | |||
| { | |||
| type: 'empty', | |||
| prompt : '选择一个镜像' | |||
| } | |||
| ] | |||
| .form({ | |||
| on: 'blur', | |||
| fields: { | |||
| image: { | |||
| identifier: 'image', | |||
| rules: [ | |||
| { | |||
| type: 'empty', | |||
| promt: '' | |||
| } | |||
| ] | |||
| }, | |||
| display_job_name: { | |||
| identifier: 'display_job_name', | |||
| rules: [ | |||
| { | |||
| type: 'regExp[/^[a-zA-Z0-9-_]{1,64}[a-zA-Z0-9_]$/]', | |||
| promt: '' | |||
| } | |||
| ] | |||
| }, | |||
| }, | |||
| onSuccess: function () { | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| }, | |||
| onFailure: function (e) { | |||
| return false; | |||
| } | |||
| }, | |||
| onSuccess: function(){ | |||
| // $('.ui.page.dimmer').dimmer('show') | |||
| document.getElementById("mask").style.display = "block" | |||
| }, | |||
| onFailure: function(e){ | |||
| return false; | |||
| } | |||
| }) | |||
| }) | |||
| } | |||
| $('.ui.create_train_job.green.button').click(function(e) { | |||
| validate() | |||
| $('.ui.create_train_job.green.button').click(function (e) { | |||
| validate() | |||
| }) | |||
| </script> | |||
| </script> | |||
| @@ -1,165 +1,199 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .according-panel-heading{ | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content{ | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border{ | |||
| border:1px solid #cce2ff; | |||
| } | |||
| .padding0{ | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad{ | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin{ | |||
| margin:10px 5px ; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 360px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content{ | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 450px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .redo-color{ | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child){ | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none!important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80{ | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according{ | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| .according-panel-heading { | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content { | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border { | |||
| border: 1px solid #cce2ff; | |||
| } | |||
| .padding0 { | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad { | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin { | |||
| margin: 10px 5px; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 425px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, | |||
| .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content { | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, | |||
| th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 450px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .redo-color { | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child) { | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none !important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80 { | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according { | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| cursor: default; | |||
| pointer-events: none; | |||
| color: rgba(0,0,0,.6) !important; | |||
| color: rgba(0, 0, 0, .6) !important; | |||
| opacity: .45 !important; | |||
| } | |||
| .pad20{ | |||
| border:0px !important; | |||
| } | |||
| .model_file_bread{ | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem ; | |||
| } | |||
| } | |||
| .pad20 { | |||
| border: 0px !important; | |||
| } | |||
| .model_file_bread { | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem; | |||
| } | |||
| </style> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| @@ -171,7 +205,7 @@ td, th { | |||
| </div> | |||
| </div> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <h4 class="ui header" id="vertical-segment"> | |||
| <div class="ui breadcrumb"> | |||
| @@ -183,11 +217,12 @@ td, th { | |||
| {{$.i18n.Tr "repo.modelarts.evaluate_job"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| </h4> | |||
| {{range $k ,$v := .version_list_task}} | |||
| <div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
| <div class="ui accordion border-according" id="accordion{{.VersionName}}" | |||
| data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="{{.ID}}" data-version="{{.VersionName}}"> | |||
| <input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||
| <div class="{{if eq $k 0}}active{{end}} title padding0"> | |||
| <div class="according-panel-heading"> | |||
| @@ -197,18 +232,23 @@ td, th { | |||
| <span> | |||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||
| <span class="cti-mgRight-sm"> | |||
| {{if not (eq .StartTime 0)}} | |||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||
| {{else}} | |||
| <td>{{TimeSinceUnix1 .CreatedUnix}}<td> | |||
| {{end}} | |||
| </span> | |||
| {{if not (eq .StartTime 0)}} | |||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||
| {{else}} | |||
| <td>{{TimeSinceUnix1 .CreatedUnix}} | |||
| <td> | |||
| {{end}} | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
| <span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span id="{{.VersionName}}-status-span"><i id="icon" | |||
| style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
| <span | |||
| class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" | |||
| id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
| </div> | |||
| </span> | |||
| @@ -219,8 +259,10 @@ td, th { | |||
| <div class="{{if eq $k 0}}active{{end}} content"> | |||
| <div class="content-pad"> | |||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
| <a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
| <a class="item" data-tab="second{{$k}}" onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
| <a class="active item" | |||
| data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
| <a class="item" data-tab="second{{$k}}" | |||
| onclick="loadLog({{.VersionName}})">{{$.i18n.Tr "repo.modelarts.log"}}</a> | |||
| </div> | |||
| <div class="ui tab active" data-tab="first{{$k}}"> | |||
| <div style="padding-top: 10px;"> | |||
| @@ -250,31 +292,61 @@ td, th { | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.start_time"}} | |||
| {{$.i18n.Tr "repo.modelarts.createtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| <span style="font-size: 12px;" class=""> | |||
| {{if not (eq .StartTime 0)}} | |||
| {{TimeSinceUnix1 .StartTime}} | |||
| {{else}} | |||
| {{TimeSinceUnix1 .CreatedUnix}} | |||
| {{end}} | |||
| {{TimeSinceUnix1 .CreatedUnix}} | |||
| </span> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.starttime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-startTime"> | |||
| {{if not (eq .StartTime 0)}} | |||
| {{TimeSinceUnix1 .StartTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-EndTime"> | |||
| {{if not (eq .EndTime 0)}} | |||
| {{TimeSinceUnix1 .EndTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-duration"> | |||
| {{$.duration}} | |||
| </div> | |||
| </td> | |||
| @@ -290,100 +362,162 @@ td, th { | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_scenes"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{.BenchmarkType}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{$.BenchmarkTypeName}} | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{.BenchmarkTypeName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| <div class="ac-grid-col"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| train.py | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| test.py | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" title="{{.Description}}"> | |||
| {{.Description}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_spec}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.User.Name}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_train"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{if eq .JobType "BENCHMARK"}} | |||
| train.py | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_test"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{if eq .JobType "BENCHMARK"}} | |||
| test.py | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.description"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" title="{{.Description}}"> | |||
| {{if .Description}} | |||
| {{.Description}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_spec}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.model_manager"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{$.datasetname}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{if .User}} | |||
| {{.User.Name}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{if eq .BenchmarkTypeName "BRAINSCORE"}} | |||
| {{$.i18n.Tr "cloudbrain.brain_area"}} | |||
| {{else}} | |||
| {{$.i18n.Tr "repo.cloudbrain.benchmark.evaluate_child_type"}} | |||
| {{end}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkChildTypeName"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-BenchmarkChildTypeName"> | |||
| {{if $.BenchmarkChildTypeName}} | |||
| {{$.BenchmarkChildTypeName}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -394,9 +528,10 @@ td, th { | |||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | |||
| <div id="header"></div> | |||
| </div> | |||
| <div class="ui attached log" id="log{{.VersionName}}" style="height: 300px !important; overflow: auto;"> | |||
| <input type="hidden" name="end_line" value> | |||
| <input type="hidden" name="start_line" value> | |||
| <div class="ui attached log" id="log{{.VersionName}}" | |||
| style="height: 300px !important; overflow: auto;"> | |||
| <input type="hidden" name="end_line" value> | |||
| <input type="hidden" name="start_line" value> | |||
| <pre id="log_file{{.VersionName}}"></pre> | |||
| </div> | |||
| @@ -437,17 +572,17 @@ td, th { | |||
| <script> | |||
| $('.menu .item').tab() | |||
| $(document).ready(function(){ | |||
| $('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||
| $(document).ready(function () { | |||
| $('.ui.accordion').accordion({ selector: { trigger: '.icon' } }); | |||
| }); | |||
| $(document).ready(function(){ | |||
| $(document).ready(function () { | |||
| $('.secondary.menu .item').tab(); | |||
| }); | |||
| let userName | |||
| let repoPath | |||
| let jobName | |||
| $(document).ready(function(){ | |||
| $(document).ready(function () { | |||
| let url = window.location.href; | |||
| let urlArr = url.split('/') | |||
| userName = urlArr.slice(-5)[0] | |||
| @@ -455,17 +590,17 @@ td, th { | |||
| jobName = urlArr.slice(-1)[0] | |||
| }) | |||
| function loadLog(version_name){ | |||
| function loadLog(version_name) { | |||
| document.getElementById("mask").style.display = "block" | |||
| $.get(`/api/v1/repos/${userName}/${repoPath}/cloudbrain/${jobName}/log?version_name=${version_name}&lines=50&order=asc`, (data) => { | |||
| $('input[name=end_line]').val(data.EndLine) | |||
| $('input[name=start_line]').val(data.StartLine) | |||
| $(`#log_file${version_name}`).text(data.Content) | |||
| document.getElementById("mask").style.display = "none" | |||
| }).fail(function(err) { | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| document.getElementById("mask").style.display = "none" | |||
| }); | |||
| } | |||
| </script> | |||
| </script> | |||
| @@ -20,8 +20,9 @@ | |||
| <span class="time-since poping up">{{.ModTime}}</span> | |||
| </td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{end}} | |||
| {{end}} | |||
| @@ -17,6 +17,7 @@ | |||
| padding-top: 100px; | |||
| color: #000000 | |||
| } | |||
| /* 加载圈css效果图 */ | |||
| #loadingPage { | |||
| @@ -58,23 +59,27 @@ | |||
| } | |||
| @-webkit-keyframes sk-stretchdelay { | |||
| 0%, | |||
| 40%, | |||
| 100% { | |||
| -webkit-transform: scaleY(0.4) | |||
| } | |||
| 20% { | |||
| -webkit-transform: scaleY(1.0) | |||
| } | |||
| } | |||
| @keyframes sk-stretchdelay { | |||
| 0%, | |||
| 40%, | |||
| 100% { | |||
| transform: scaleY(0.4); | |||
| -webkit-transform: scaleY(0.4); | |||
| } | |||
| 20% { | |||
| transform: scaleY(1.0); | |||
| -webkit-transform: scaleY(1.0); | |||
| @@ -93,15 +98,12 @@ | |||
| display: none; | |||
| } | |||
| .icons{ | |||
| .icons { | |||
| /* position: absolute !important; | |||
| right: 150px; | |||
| top: 14px; | |||
| z-index: 2; */ | |||
| } | |||
| </style> | |||
| <div id="mask"> | |||
| @@ -117,7 +119,7 @@ | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| <div class="repository new repo ui middle very relaxed page grid"> | |||
| <div class="column"> | |||
| {{template "base/alert" .}} | |||
| <div class="ui negative message" id="messageInfo"> | |||
| @@ -133,43 +135,45 @@ | |||
| <label>{{.i18n.Tr "cloudbrain.compute_resource"}}</label> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="active item" href="{{.RepoLink}}/cloudbrain/create"> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||
| <path fill="none" d="M0 0h24v24H0z"/> | |||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
| height="16"> | |||
| <path fill="none" d="M0 0h24v24H0z" /> | |||
| <path | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| CPU/GPU | |||
| </a> | |||
| <a class="item" href="{{.RepoLink}}/modelarts/notebook/create"> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16"> | |||
| <path fill="none" d="M0 0h24v24H0z"/> | |||
| <path d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z"/> | |||
| <svg class="svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" | |||
| height="16"> | |||
| <path fill="none" d="M0 0h24v24H0z" /> | |||
| <path | |||
| d="M3 2.992C3 2.444 3.445 2 3.993 2h16.014a1 1 0 0 1 .993.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 21.008V2.992zM19 11V4H5v7h14zm0 2H5v7h14v-7zM9 6h6v2H9V6zm0 9h6v2H9v-2z" /> | |||
| </svg> | |||
| Ascend NPU</a> | |||
| </div> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.task_name"}}</label> | |||
| <input name="display_job_name" id="cloudbrain_job_name" placeholder="input {{.i18n.Tr "cloudbrain.task_name"}}" value="{{.display_job_name}}" tabindex="3" autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| <input name="display_job_name" id="cloudbrain_job_name" | |||
| placeholder="{{.i18n.Tr "cloudbrain.task_name"}}" value="{{.display_job_name}}" tabindex="3" | |||
| autofocus required maxlength="255" onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.task_type"}}</label> | |||
| <select id="cloudbrain_job_type" class="ui search dropdown" placeholder="select {{.i18n.Tr "cloudbrain.task_type"}}" style='width:385px' name="job_type"> | |||
| <select id="cloudbrain_job_type" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.task_type"}}" style='width:385px' name="job_type"> | |||
| <option name="job_type" value="DEBUG">DEBUG</option> | |||
| {{if .is_snn4imagenet_enabled}} | |||
| <option name="job_type" value="SNN4IMAGENET">SNN4IMAGENET</option> | |||
| {{end}} | |||
| {{if .is_brainscore_enabled}} | |||
| <option name="job_type" value="BRAINSCORE">BRAINSCORE</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="inline required field cloudbrain_benchmark"> | |||
| <label style="vertical-align: top; margin-top:9px">数据集类别</label> | |||
| <select class="ui search dropdown" multiple="multiple" id="cloudbrain_benchmark_category" style='width:385px'> | |||
| <select class="ui search dropdown" multiple="multiple" id="cloudbrain_benchmark_category" | |||
| style='width:385px'> | |||
| {{range .benchmark_categories}} | |||
| <option value="{{.Value}}">{{.Value}}</option> | |||
| <option value="{{.Value}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| <div class="mini ui buttons" style="vertical-align: top; margin-top:9px"> | |||
| @@ -178,32 +182,33 @@ | |||
| <button class="ui positive button active all_selected">全选</button> | |||
| </div> | |||
| </div> | |||
| <input id="store_category" type="hidden" name="get_benchmark_category"> | |||
| <input id="store_category" type="hidden" name="get_benchmark_category"> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "repo.modelarts.code_version"}}</label> | |||
| <select class="ui dropdown width80 left2" id="code_version" name="branch_name"> | |||
| {{if .branch_name}} | |||
| <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||
| {{range $k, $v :=.Branches}} | |||
| {{ if ne $v $.branch_name }} | |||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| <option name="branch_name" value="{{.branch_name}}">{{.branch_name}}</option> | |||
| {{range $k, $v :=.Branches}} | |||
| {{ if ne $v $.branch_name }} | |||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{else}} | |||
| <option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||
| {{range $k, $v :=.Branches}} | |||
| {{ if ne $v $.branchName }} | |||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| <option name="branch_name" value="{{.branchName}}">{{.branchName}}</option> | |||
| {{range $k, $v :=.Branches}} | |||
| {{ if ne $v $.branchName }} | |||
| <option name="branch_name" value="{{$v}}">{{$v}}</option> | |||
| {{end}} | |||
| {{end}} | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.gpu_type"}}</label> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" style='width:385px' name="gpu_type"> | |||
| <select id="cloudbrain_gpu_type" class="ui search dropdown" placeholder="选择GPU类型" | |||
| style='width:385px' name="gpu_type"> | |||
| {{range .gpu_types}} | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| <option value="{{.Queue}}">{{.Value}}</option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| @@ -224,40 +229,50 @@ | |||
| <div id="images-new-cb"> | |||
| </div> | |||
| {{template "custom/select_dataset" .}} | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.resource_specification"}}</label> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' name="resource_spec_id"> | |||
| <select id="cloudbrain_resource_spec" class="ui search dropdown" | |||
| placeholder="{{.i18n.Tr "cloudbrain.select_specification"}}" style='width:385px' | |||
| name="resource_spec_id"> | |||
| {{range .resource_specs}} | |||
| <option name="resource_spec_id" value="{{.Id}}">{{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}}</option> | |||
| <option name="resource_spec_id" value="{{.Id}}"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{.ShareMemMiB}} | |||
| </option> | |||
| {{end}} | |||
| </select> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.dataset_storage_path"}}</label> | |||
| <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| <input name="dataset_path" id="cloudbrain_dataset_path" value="{{.dataset_path}}" tabindex="3" | |||
| disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.model_storage_path"}}</label> | |||
| <input name="model_path" id="cloudbrain_model_path" value="{{.model_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| <input name="model_path" id="cloudbrain_model_path" value="{{.model_path}}" tabindex="3" | |||
| disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field"> | |||
| <label>{{.i18n.Tr "cloudbrain.code_storage_path"}}</label> | |||
| <input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| <input name="code_path" id="cloudbrain_code_path" value="{{.code_path}}" tabindex="3" disabled | |||
| autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field cloudbrain_benchmark"> | |||
| <label>{{.i18n.Tr "cloudbrain.benchmark_path"}}</label> | |||
| <input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| <input name="benchmark_path" id="cloudbrain_benchmark_path" value="{{.benchmark_path}}" | |||
| tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field cloudbrain_snn4imagenet"> | |||
| <label>{{.i18n.Tr "cloudbrain.snn4imagenet_path"}}</label> | |||
| <input name="snn4imagenet_path" id="cloudbrain_snn4imagenet_path" value="{{.snn4imagenet_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| <input name="snn4imagenet_path" id="cloudbrain_snn4imagenet_path" value="{{.snn4imagenet_path}}" | |||
| tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field cloudbrain_brainscore"> | |||
| <label>{{.i18n.Tr "cloudbrain.brainscore_path"}}</label> | |||
| <input name="brainscore_path" id="cloudbrain_brainscore_path" value="{{.brainscore_path}}" tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| <input name="brainscore_path" id="cloudbrain_brainscore_path" value="{{.brainscore_path}}" | |||
| tabindex="3" disabled autofocus required maxlength="255" readonly="readonly"> | |||
| </div> | |||
| <div class="inline required field" hidden> | |||
| <label>{{.i18n.Tr "cloudbrain.start_command"}}</label> | |||
| @@ -266,10 +281,11 @@ | |||
| <div class="inline field"> | |||
| <label></label> | |||
| <button class="ui green button" > | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button cancel" href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| <button class="ui green button"> | |||
| {{.i18n.Tr "repo.cloudbrain.new"}} | |||
| </button> | |||
| <a class="ui button cancel" | |||
| href="{{.RepoLink}}/debugjob?debugListType=all">{{.i18n.Tr "repo.cloudbrain.cancel"}}</a> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| @@ -287,32 +303,32 @@ | |||
| // $(".icon.icons").css("visibility","visible") | |||
| // }); | |||
| $('#messageInfo').css('display','none') | |||
| function clearValue(){ | |||
| context=inputs[0] | |||
| context.value='' | |||
| $(".icon.icons").css("visibility","hidden") | |||
| $('#messageInfo').css('display', 'none') | |||
| function clearValue() { | |||
| context = inputs[0] | |||
| context.value = '' | |||
| $(".icon.icons").css("visibility", "hidden") | |||
| } | |||
| form.onsubmit = function(e){ | |||
| form.onsubmit = function (e) { | |||
| let value_task = $("input[name='display_job_name']").val() | |||
| let value_image = $("input[name='image']").val() | |||
| let value_data = $("input[name='attachment']").val() | |||
| let re = /^[a-z0-9][a-z0-9-_]{1,34}[a-z0-9-]$/ | |||
| let flag = re.test(value_task) | |||
| if(!flag){ | |||
| $('#messageInfo').css('display','block') | |||
| if (!flag) { | |||
| $('#messageInfo').css('display', 'block') | |||
| let str = '只能以小写字母或数字开头且只包含小写字母、数字、_和-,不能以_结尾,最长36个字符。' | |||
| $('#messageInfo p').text(str) | |||
| return false | |||
| } | |||
| let min_value_task = value_task.toLowerCase() | |||
| $("input[name='display_job_name']").attr("value",min_value_task) | |||
| $("input[name='display_job_name']").attr("value", min_value_task) | |||
| document.getElementById("mask").style.display = "block" | |||
| } | |||
| // 页面加载完毕后遮罩层隐藏 | |||
| document.onreadystatechange = function() { | |||
| document.onreadystatechange = function () { | |||
| if (document.readyState === "complete") { | |||
| document.getElementById("mask").style.display = "none" | |||
| } | |||
| @@ -332,24 +348,24 @@ | |||
| // }); | |||
| $(".ui.button.reset").click(function(e){ | |||
| $(".ui.button.reset").click(function (e) { | |||
| e.preventDefault() | |||
| $('#cloudbrain_benchmark_category') | |||
| .dropdown("clear", true) | |||
| .dropdown("clear", true) | |||
| }) | |||
| $(".ui.positive.button.active.all_selected").click(function(e){ | |||
| $(".ui.positive.button.active.all_selected").click(function (e) { | |||
| e.preventDefault() | |||
| var selected_value = new Array() | |||
| $("#cloudbrain_benchmark_category option").each(function(){ | |||
| $("#cloudbrain_benchmark_category option").each(function () { | |||
| selected_value.push($(this).val()) | |||
| }); | |||
| $('#cloudbrain_benchmark_category') | |||
| .dropdown("set exactly", selected_value) | |||
| .dropdown("set exactly", selected_value) | |||
| }) | |||
| $(function() { | |||
| $("#cloudbrain_job_type").change(function() { | |||
| $(function () { | |||
| $("#cloudbrain_job_type").change(function () { | |||
| if ($(this).val() == 'BENCHMARK') { | |||
| $(".cloudbrain_benchmark").show(); | |||
| } else if ($(this).val() == 'SNN4IMAGENET') { | |||
| @@ -364,10 +380,10 @@ | |||
| }) | |||
| }) | |||
| $('.ui.green.button').click(function() { | |||
| $('.ui.green.button').click(function () { | |||
| selected_value = $("#cloudbrain_benchmark_category").val() | |||
| $('#store_category').attr("value", selected_value) | |||
| }) | |||
| </script> | |||
| </script> | |||
| @@ -1,171 +1,205 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .according-panel-heading{ | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content{ | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border{ | |||
| border:1px solid #cce2ff; | |||
| } | |||
| .padding0{ | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad{ | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin{ | |||
| margin:10px 5px ; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 420px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .info_text { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| font-size: 12px; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content{ | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 450px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .redo-color{ | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child){ | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none!important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80{ | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according{ | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| .according-panel-heading { | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content { | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border { | |||
| border: 1px solid #cce2ff; | |||
| } | |||
| .padding0 { | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad { | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin { | |||
| margin: 10px 5px; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 420px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, | |||
| .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .info_text { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| font-size: 12px; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content { | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, | |||
| th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 450px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .redo-color { | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child) { | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none !important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80 { | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according { | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| cursor: default; | |||
| pointer-events: none; | |||
| color: rgba(0,0,0,.6) !important; | |||
| color: rgba(0, 0, 0, .6) !important; | |||
| opacity: .45 !important; | |||
| } | |||
| .pad20{ | |||
| border:0px !important; | |||
| } | |||
| .model_file_bread{ | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem ; | |||
| } | |||
| } | |||
| .pad20 { | |||
| border: 0px !important; | |||
| } | |||
| .model_file_bread { | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem; | |||
| } | |||
| </style> | |||
| @@ -179,7 +213,7 @@ td, th { | |||
| </div> | |||
| </div> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <h4 class="ui header" id="vertical-segment"> | |||
| <div class="ui breadcrumb"> | |||
| @@ -191,11 +225,12 @@ td, th { | |||
| {{$.i18n.Tr "repo.modelarts.notebook"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| <div class="active section">{{.displayJobName}}</div> | |||
| </div> | |||
| </h4> | |||
| {{range $k ,$v := .version_list_task}} | |||
| <div class="ui accordion border-according" id="accordion{{.VersionName}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}" data-version="{{.VersionName}}"> | |||
| <div class="ui accordion border-according" id="accordion{{.VersionName}}" | |||
| data-repopath="{{$.RepoRelPath}}/cloudbrain" data-jobid="{{.ID}}" data-version="{{.VersionName}}"> | |||
| <input type="hidden" id="jobId_input" name="jobId_input" value="{{.JobID}}"> | |||
| <div class="{{if eq $k 0}}active{{end}} title padding0"> | |||
| <div class="according-panel-heading"> | |||
| @@ -205,19 +240,26 @@ td, th { | |||
| <span> | |||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||
| <span class="cti-mgRight-sm"> | |||
| {{if not (eq .StartTime 0)}} | |||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||
| {{else}} | |||
| <td>{{TimeSinceUnix1 .CreatedUnix}}<td> | |||
| {{end}} | |||
| </span> | |||
| {{if not (eq .StartTime 0)}} | |||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||
| {{else}} | |||
| <td>{{TimeSinceUnix1 .CreatedUnix}} | |||
| <td> | |||
| {{end}} | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
| <span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span id="{{.VersionName}}-status-span"><i id="icon" | |||
| style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}: | |||
| </span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" | |||
| id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
| <span data-tooltip="刷新" style="cursor: pointer;" data-inverted="" | |||
| onclick="refreshStatus({{.VersionName}})"><i | |||
| class="redo icon redo-color"></i></span> | |||
| </div> | |||
| </span> | |||
| </span> | |||
| @@ -227,8 +269,10 @@ td, th { | |||
| <div class="{{if eq $k 0}}active{{end}} content"> | |||
| <div class="content-pad"> | |||
| <div class="ui pointing secondary menu" style="border-bottom: 1px solid rgba(34,36,38,.15);"> | |||
| <a class="active item" data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
| <a class="item" data-tab="second{{$k}}" onclick="javascript:parseLog()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | |||
| <a class="active item" | |||
| data-tab="first{{$k}}">{{$.i18n.Tr "repo.modelarts.train_job.config"}}</a> | |||
| <a class="item" data-tab="second{{$k}}" | |||
| onclick="javascript:parseLog()">{{$.i18n.Tr "repo.cloudbrain.runinfo"}}</a> | |||
| </div> | |||
| <div class="ui tab active" data-tab="first{{$k}}"> | |||
| <div style="padding-top: 10px;"> | |||
| @@ -259,192 +303,199 @@ td, th { | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.User.Name}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.User.Name}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.computing_resources"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-computeresource"> | |||
| {{.ComputeResource}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.computing_resources"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-computeresource"> | |||
| {{.ComputeResource}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.task_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-computeresource"> | |||
| {{.JobType}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-code"> | |||
| {{.BranchName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.task_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-computeresource"> | |||
| {{.JobType}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.code_version"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-code"> | |||
| {{.BranchName}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.createtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-createtime"> | |||
| {{TimeSinceUnix1 .CreatedUnix}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_type"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_type}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-duration"> | |||
| {{$.duration}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.createtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-createtime"> | |||
| {{TimeSinceUnix1 .CreatedUnix}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dura_time"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
| {{$.duration}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| <div class="ac-grid-col"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.mirror"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.Image}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{$.datasetname}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.dataset_storage_path"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="dataset_storage_path"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.mirror"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.Image}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{$.datasetname}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.i18n.Tr "cloudbrain.gpu_num"}}:{{$.GpuNum}},{{$.i18n.Tr "cloudbrain.cpu_num"}}:{{$.CpuNum}},{{$.i18n.Tr "cloudbrain.memory"}}(MB):{{$.MemMiB}},{{$.i18n.Tr "cloudbrain.shared_memory"}}(MB):{{$.ShareMemMiB}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.dataset_storage_path"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="dataset_storage_path"> | |||
| {{$.dataset_path}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.model_storage_path"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="model_storage_path"> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.model_storage_path"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="model_storage_path"> | |||
| {{$.model_path}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.code_storage_path"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="code_storage_path"> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.code_storage_path"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="code_storage_path"> | |||
| {{$.code_path}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.starttime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-startTime"> | |||
| {{if not (eq .StartTime 0)}} | |||
| {{TimeSinceUnix1 .StartTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-EndTime"> | |||
| {{if not (eq .EndTime 0)}} | |||
| {{TimeSinceUnix1 .EndTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.starttime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-startTime"> | |||
| {{if not (eq .StartTime 0)}} | |||
| {{TimeSinceUnix1 .StartTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-EndTime"> | |||
| {{if not (eq .EndTime 0)}} | |||
| {{TimeSinceUnix1 .EndTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -455,10 +506,11 @@ td, th { | |||
| <div class="ui message message{{.VersionName}}" style="display: none;"> | |||
| <div id="header"></div> | |||
| </div> | |||
| <div class="ui attached log" id="log{{.VersionName}}" style="height: 390px !important; overflow: auto;"> | |||
| <div class="ui attached log" id="log{{.VersionName}}" | |||
| style="height: 390px !important; overflow: auto;"> | |||
| <input type="hidden" id="json_value" value="{{$.result.JobStatus.AppExitDiagnostics}}"> | |||
| <span id="info_display" class="info_text"> | |||
| </span> | |||
| </div> | |||
| @@ -498,38 +550,71 @@ td, th { | |||
| <script> | |||
| $('.menu .item').tab() | |||
| $(document).ready(function(){ | |||
| $('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||
| $(document).ready(function () { | |||
| $('.ui.accordion').accordion({ selector: { trigger: '.icon' } }); | |||
| }); | |||
| $(document).ready(function(){ | |||
| $(document).ready(function () { | |||
| $('.secondary.menu .item').tab(); | |||
| }); | |||
| function parseLog(){ | |||
| let jsonValue = document.getElementById("json_value").value; | |||
| let jsonObj = JSON.parse(jsonValue); | |||
| let podRoleName = jsonObj["podRoleName"]; | |||
| let html = ""; | |||
| if (podRoleName != null){ | |||
| let task0 = podRoleName["task1-0"]; | |||
| let podEvents = jsonObj["podEvents"]; | |||
| let podEventArray = podEvents[task0]; | |||
| if(podEventArray != null){ | |||
| for(var i=0; i < podEventArray.length;i++){ | |||
| html +="<p><b>[" +podEventArray[i]["reason"] + "]</b></p>"; | |||
| html +="<p>" +podEventArray[i]["message"] + "</p>"; | |||
| html +="<p>" +podEventArray[i]["action"] + "</p>"; | |||
| } | |||
| } | |||
| let extras= jsonObj["extras"]; | |||
| if(extras != null){ | |||
| for(var i=0; i < extras.length;i++){ | |||
| html +="<p><b>[" +extras[i]["reason"] + "]</b></p>"; | |||
| html +="<p>" +extras[i]["message"] + "</p>"; | |||
| html +="<p>" +extras[i]["action"] + "</p>"; | |||
| function parseLog() { | |||
| let jsonValue = document.getElementById("json_value").value; | |||
| let jsonObj = JSON.parse(jsonValue); | |||
| let podRoleName = jsonObj["podRoleName"]; | |||
| let html = ""; | |||
| if (podRoleName != null) { | |||
| let task0 = podRoleName["task1-0"]; | |||
| let podEvents = jsonObj["podEvents"]; | |||
| let podEventArray = podEvents[task0]; | |||
| if (podEventArray != null) { | |||
| for (var i = 0; i < podEventArray.length; i++) { | |||
| if (podEventArray[i]["reason"] != "") { | |||
| html += "<p><b>[" + podEventArray[i]["reason"] + "]</b></p>"; | |||
| html += "<p>" + podEventArray[i]["message"] + "</p>"; | |||
| html += "<p>" + podEventArray[i]["action"] + "</p>"; | |||
| } | |||
| } | |||
| } | |||
| let extras = jsonObj["extras"]; | |||
| if (extras != null) { | |||
| for (var i = 0; i < extras.length; i++) { | |||
| if (extras[i]["reason"] != "") { | |||
| html += "<p><b>[" + extras[i]["reason"] + "]</b></p>"; | |||
| html += "<p>" + extras[i]["message"] + "</p>"; | |||
| html += "<p>" + extras[i]["action"] + "</p>"; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| document.getElementById("info_display").innerHTML = html; | |||
| } | |||
| function stopBubbling(e) { | |||
| e = window.event || e; | |||
| if (e.stopPropagation) { | |||
| e.stopPropagation(); //阻止事件 冒泡传播 | |||
| } else { | |||
| e.cancelBubble = true; //ie兼容 | |||
| } | |||
| } | |||
| function refreshStatus(version_name) { | |||
| $(".ui.accordion.border-according").each((index, job) => { | |||
| const jobID = job.dataset.jobid; | |||
| const repoPath = job.dataset.repopath; | |||
| const versionname = job.dataset.version | |||
| $.get(`/api/v1/repos/${repoPath}/cloudbrain/${jobID}?version_name=${versionname}`, (data) => { | |||
| // header status and duration | |||
| //$(`#${version_name}-duration-span`).text(data.JobDuration) | |||
| $(`#${version_name}-status-span span`).text(data.JobStatus) | |||
| $(`#${version_name}-status-span i`).attr("class", data.JobStatus) | |||
| // detail status and duration | |||
| //$('#'+version_name+'-duration').text(data.JobDuration) | |||
| $('#' + version_name + '-status').text(data.JobStatus) | |||
| parseLog() | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| stopBubbling(arguments.callee.caller.arguments[0]) | |||
| }) | |||
| } | |||
| document.getElementById("info_display").innerHTML=html; | |||
| } | |||
| </script> | |||
| @@ -1,41 +1,47 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .selectcloudbrain .active.item{ | |||
| color: #0087f5 !important; | |||
| border: 1px solid #0087f5; | |||
| margin: -1px; | |||
| background: #FFF !important; | |||
| } | |||
| .selectcloudbrain .active.item { | |||
| color: #0087f5 !important; | |||
| border: 1px solid #0087f5; | |||
| margin: -1px; | |||
| background: #FFF !important; | |||
| } | |||
| .dataset_title{ | |||
| font-size: 14px; | |||
| .dataset_title { | |||
| font-size: 14px; | |||
| max-width: 80%; | |||
| display: inline-block !important; | |||
| margin-left: 6px !important; | |||
| padding-right: 0 !important; | |||
| } | |||
| .wrapper { | |||
| } | |||
| .wrapper { | |||
| display: flex; | |||
| overflow: hidden; | |||
| padding: 0 1rem; | |||
| } | |||
| .exp{ | |||
| } | |||
| .exp { | |||
| display: none; | |||
| } | |||
| .exp:checked+.text{ | |||
| } | |||
| .exp:checked+.text { | |||
| max-height: none; | |||
| } | |||
| .exp:checked+.text::after{ | |||
| } | |||
| .exp:checked+.text::after { | |||
| visibility: hidden; | |||
| } | |||
| .exp:checked+.text .btn::before{ | |||
| } | |||
| .exp:checked+.text .btn::before { | |||
| visibility: hidden; | |||
| } | |||
| .exp:checked+.text .btn::after{ | |||
| } | |||
| .exp:checked+.text .btn::after { | |||
| content:'{{$.i18n.Tr "org.fold"}}' | |||
| } | |||
| } | |||
| .wrapper>.text { | |||
| .wrapper>.text { | |||
| font-family: SourceHanSansSC-regular; | |||
| font-size: 14px; | |||
| color: #101010; | |||
| @@ -48,21 +54,24 @@ | |||
| transition: .3s max-height; | |||
| word-wrap: break-word; | |||
| word-break: break-all; | |||
| } | |||
| .wrapper>.text::before { | |||
| } | |||
| .wrapper>.text::before { | |||
| content: ''; | |||
| height: calc(100% - 20px); | |||
| float: right; | |||
| } | |||
| .wrapper>.text::after { | |||
| } | |||
| .wrapper>.text::after { | |||
| content: ''; | |||
| width: 999vw; | |||
| height: 999vw; | |||
| position: absolute; | |||
| box-shadow: inset calc(100px - 999vw) calc(30px - 999vw) 0 0 #fff; | |||
| margin-left: -100px; | |||
| } | |||
| .btn{ | |||
| } | |||
| .btn { | |||
| position: relative; | |||
| float: right; | |||
| clear: both; | |||
| @@ -72,181 +81,212 @@ | |||
| background: #3F51B5; | |||
| line-height: 20px; | |||
| border-radius: 4px; | |||
| color: #fff; | |||
| color: #fff; | |||
| cursor: pointer; | |||
| /* margin-top: -30px; */ | |||
| } | |||
| .btn::after{ | |||
| } | |||
| .btn::after { | |||
| content:'{{$.i18n.Tr "org.unfold"}}' | |||
| } | |||
| .btn::before{ | |||
| } | |||
| .btn::before { | |||
| content: '...'; | |||
| position: absolute; | |||
| left: -5px; | |||
| color: #333; | |||
| transform: translateX(-100%) | |||
| } | |||
| } | |||
| .el-button--text { | |||
| color: #0366d6; | |||
| } | |||
| .heart-stroke { | |||
| stroke: #666; | |||
| stroke-width: 2; | |||
| fill: #fff | |||
| } | |||
| .el-button--text{color:#0366d6 ;} | |||
| .heart-stroke{ | |||
| stroke: #666; | |||
| stroke-width: 2; | |||
| fill: #fff | |||
| } | |||
| .stars_active{ | |||
| fill: #FA8C16 !important; | |||
| stroke:#FA8C16 !important | |||
| } | |||
| .diy-popper{ | |||
| max-width: 400px; | |||
| } | |||
| .stars_active { | |||
| fill: #FA8C16 !important; | |||
| stroke: #FA8C16 !important | |||
| } | |||
| .diy-popper { | |||
| max-width: 400px; | |||
| } | |||
| </style> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| {{if .dataset}} | |||
| <div id="dataset-range-value" data-num-stars="{{.dataset.NumStars}}" data-star-active="{{$.IsStaringDataset}}" style="display: none;"> | |||
| {{range .Attachments}} | |||
| <div class="item" data-private="{{.IsPrivate}}" data-decompress-state="{{.DecompressState}}"></div> | |||
| <div id="dataset-range-value" data-num-stars="{{.dataset.NumStars}}" data-star-active="{{$.IsStaringDataset}}" | |||
| style="display: none;"> | |||
| {{range .Attachments}} | |||
| <div class="item" data-private="{{.IsPrivate}}" data-decompress-state="{{.DecompressState}}"></div> | |||
| {{end}} | |||
| </div> | |||
| <div id="dataset-base"> | |||
| <div class="ui container"> | |||
| <div class="ui mobile reversed stackable grid"> | |||
| <div class="row"> | |||
| <div class="column thirteen wide"><h2>{{.dataset.Title}}</h2></div> | |||
| <div class="column thirteen wide"> | |||
| <h2>{{.dataset.Title}}</h2> | |||
| </div> | |||
| <div class="column three wide right aligned"> | |||
| <span style="display: flex;align-items: center;justify-content: flex-end;height: 36px;"> | |||
| {{if $.IsSigned}} | |||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;" @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" :class='{stars_active:star_active}'><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||
| </div> | |||
| <span style="line-height: 1;">${num_stars}</span> | |||
| {{else}} | |||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;"> | |||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" :class='{stars_active:star_active}'><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||
| </div> | |||
| <span style="line-height: 1;">${num_stars}</span> | |||
| {{end}} | |||
| <a style="margin-left:30px;" href="{{.RepoLink}}/datasets/edit/{{.dataset.ID}}" class="ui primary basic mini {{if not $.CanWrite}} disabled {{end}} button">{{.i18n.Tr "repo.modelarts.modify"}}</a> | |||
| </span> | |||
| <span style="display: flex;align-items: center;justify-content: flex-end;height: 36px;"> | |||
| {{if $.IsSigned}} | |||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;" | |||
| @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" | |||
| :class='{stars_active:star_active}'> | |||
| <path | |||
| d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"> | |||
| </path> | |||
| </svg> | |||
| </div> | |||
| <span style="line-height: 1;">${num_stars}</span> | |||
| {{else}} | |||
| <div style="line-height: 1;margin-right: 4px;margin-bottom: -2px;padding: 0 10px;"> | |||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke" | |||
| :class='{stars_active:star_active}'> | |||
| <path | |||
| d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"> | |||
| </path> | |||
| </svg> | |||
| </div> | |||
| <span style="line-height: 1;">${num_stars}</span> | |||
| {{end}} | |||
| <a style="margin-left:30px;" href="{{.RepoLink}}/datasets/edit/{{.dataset.ID}}" | |||
| class="ui primary basic mini {{if not $.CanWrite}} disabled {{end}} button">{{.i18n.Tr "repo.modelarts.modify"}}</a> | |||
| </span> | |||
| </div> | |||
| {{if or (.dataset.Category) (.dataset.Task) (.dataset.License)}} | |||
| <div class="column thirteen wide"> | |||
| {{if .dataset.Category}} | |||
| {{$category := .dataset.Category}} | |||
| <a class="ui repo-topic label topic" href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{.dataset.Category}}&task={{$.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.category.%s" $category)}}</a> | |||
| {{end}} | |||
| {{if .dataset.Task}} | |||
| {{$task := .dataset.Task}} | |||
| <a class="ui repo-topic label topic" href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{.dataset.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.task.%s" $task)}}</a> | |||
| {{end}} | |||
| {{if .dataset.License}} | |||
| <a class="ui repo-topic label topic" href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{.dataset.License}}">{{.dataset.License}}</a> | |||
| {{end}} | |||
| {{if .dataset.Category}} | |||
| {{$category := .dataset.Category}} | |||
| <a class="ui repo-topic label topic" | |||
| href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{.dataset.Category}}&task={{$.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.category.%s" $category)}}</a> | |||
| {{end}} | |||
| {{if .dataset.Task}} | |||
| {{$task := .dataset.Task}} | |||
| <a class="ui repo-topic label topic" | |||
| href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{.dataset.Task}}&license={{$.License}}">{{$.i18n.Tr (printf "dataset.task.%s" $task)}}</a> | |||
| {{end}} | |||
| {{if .dataset.License}} | |||
| <a class="ui repo-topic label topic" | |||
| href="{{AppSubUrl}}/explore/datasets?sort={{$.SortType}}&q={{$.Keyword}}&tab={{$.TabName}}&category={{$.Category}}&task={{$.Task}}&license={{.dataset.License}}">{{.dataset.License}}</a> | |||
| {{end}} | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{if .dataset.Description}} | |||
| <div class="row" style="padding-top: 0;"> | |||
| <div class=" wrapper"> | |||
| <input id="exp1" class="exp" type="checkbox"> | |||
| <div class="text"> | |||
| <label class="btn" for="exp1"></label> | |||
| {{.dataset.Description}} | |||
| </div> | |||
| <div class=" wrapper"> | |||
| <input id="exp1" class="exp" type="checkbox"> | |||
| <div class="text"> | |||
| <label class="btn" for="exp1"></label> | |||
| {{.dataset.Description}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| <div class="row"> | |||
| <div class="column ten wide"></div> | |||
| <div class="column six wide right aligned"> | |||
| <el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType"> | |||
| <i slot="prefix" style="display: inline-block;color: #101010;" class="el-input__icon ri-archive-drawer-line"></i> | |||
| <el-option label="{{$.i18n.Tr "repo.gpu_type_all"}}" value="-1"></el-option> | |||
| <el-option label="CPU/GPU" value="0"></el-option> | |||
| <el-option label="NPU" value="1"></el-option> | |||
| </el-select> | |||
| <el-button icon="el-icon-upload" {{if not $.CanWrite}} disabled {{end}} type="primary" size="small" @click="gotoUpload('{{.RepoLink}}',{{.dataset.ID}})">{{$.i18n.Tr "dataset.dataset_upload"}}</el-button> | |||
| <el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType"> | |||
| <i slot="prefix" style="display: inline-block;color: #101010;" | |||
| class="el-input__icon ri-archive-drawer-line"></i> | |||
| <el-option label="{{$.i18n.Tr "repo.gpu_type_all"}}" value="-1"></el-option> | |||
| <el-option label="CPU/GPU" value="0"></el-option> | |||
| <el-option label="NPU" value="1"></el-option> | |||
| </el-select> | |||
| <el-button icon="el-icon-upload" {{if not $.CanWrite}} disabled {{end}} type="primary" size="small" | |||
| @click="gotoUpload('{{.RepoLink}}',{{.dataset.ID}})">{{$.i18n.Tr "dataset.dataset_upload"}}</el-button> | |||
| </div> | |||
| </div> | |||
| <div class="row"> | |||
| <div class="ui sixteen wide column dataset"> | |||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
| <div class="row"> | |||
| <!-- 数据集名称 --> | |||
| <div class="four wide column" style="width: 24% !important;"> | |||
| <span style="margin:0 6px">{{$.i18n.Tr "dataset.dataset_file_name"}}</span> | |||
| </div> | |||
| <div class="one wide column text center" style="width: 7.25% !important;"> | |||
| {{$.i18n.Tr "repo.model.manage.size"}} | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| {{$.i18n.Tr "dataset.dataset_available_clusters"}} | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{$.i18n.Tr "repo.modelarts.status"}} | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </div> | |||
| <div class="three wide column text center"> | |||
| {{$.i18n.Tr "dataset.dataset_upload_time"}} | |||
| </div> | |||
| <div class="four wide column text center"> | |||
| {{$.i18n.Tr "repo.cloudbrain_operate"}} | |||
| </div> | |||
| </div> | |||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
| <div class="row"> | |||
| <!-- 数据集名称 --> | |||
| <div class="four wide column" style="width: 24% !important;"> | |||
| <span style="margin:0 6px">{{$.i18n.Tr "dataset.dataset_file_name"}}</span> | |||
| </div> | |||
| <div class="one wide column text center" style="width: 7.25% !important;"> | |||
| {{$.i18n.Tr "repo.model.manage.size"}} | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| {{$.i18n.Tr "dataset.dataset_available_clusters"}} | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{$.i18n.Tr "repo.modelarts.status"}} | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </div> | |||
| <div class="three wide column text center"> | |||
| {{$.i18n.Tr "dataset.dataset_upload_time"}} | |||
| </div> | |||
| <div class="four wide column text center"> | |||
| {{$.i18n.Tr "repo.cloudbrain_operate"}} | |||
| </div> | |||
| </div> | |||
| {{range $k, $v :=.Attachments}} | |||
| <div class="ui grid stackable item" id="{{.UUID}}"> | |||
| <div class="row"> | |||
| <!-- 数据集名称 --> | |||
| </div> | |||
| {{range $k, $v :=.Attachments}} | |||
| <div class="ui grid stackable item" id="{{.UUID}}"> | |||
| <div class="row"> | |||
| <!-- 数据集名称 --> | |||
| <div class="four wide column" style="width: 24% !important;display: flex;align-items: center;"> | |||
| {{if .Description}} | |||
| <el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper"> | |||
| <div slot="content" >{{.Description}}</br><span><i class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}</span></div> | |||
| <a class="dataset_title title" href="{{.DownloadURL}}" title="{{.Name}}" style="border: none;"> | |||
| {{.Name}} | |||
| </a> | |||
| </el-tooltip> | |||
| {{else}} | |||
| <el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper"> | |||
| <div slot="content" ><span><i class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}</span></div> | |||
| <a class="dataset_title title" href="{{.DownloadURL}}" title="{{.Name}}" style="border: none;"> | |||
| {{.Name}} | |||
| </a> | |||
| </el-tooltip> | |||
| {{end}} | |||
| <i class="ri-lock-2-line" style="color: #fa8c16;" v-if="privates[{{$k}}]"></i> | |||
| <!-- <i class="COMPLETED" v-if="zipStatus[{{$k}}]==1"></i> | |||
| <div class="four wide column" style="width: 24% !important;display: flex;align-items: center;"> | |||
| {{if .Description}} | |||
| <el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper"> | |||
| <div slot="content">{{.Description}}</br><span><i | |||
| class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}</span></div> | |||
| <a class="dataset_title title" href="{{.DownloadURL}}" title="{{.Name}}" style="border: none;"> | |||
| {{.Name}} | |||
| </a> | |||
| </el-tooltip> | |||
| {{else}} | |||
| <el-tooltip class="item" effect="dark" placement="top" popper-class="diy-popper"> | |||
| <div slot="content"><span><i | |||
| class="ri-download-line"></i>{{$.i18n.Tr "dataset.download"}}:{{.DownloadCount}}</span></div> | |||
| <a class="dataset_title title" href="{{.DownloadURL}}" title="{{.Name}}" style="border: none;"> | |||
| {{.Name}} | |||
| </a> | |||
| </el-tooltip> | |||
| {{end}} | |||
| <i class="ri-lock-2-line" style="color: #fa8c16;" v-if="privates[{{$k}}]"></i> | |||
| <!-- <i class="COMPLETED" v-if="zipStatus[{{$k}}]==1"></i> | |||
| <i class="WAITING" v-if="zipStatus[{{$k}}]==2"></i> | |||
| <i class="FAILED" v-if="zipStatus[{{$k}}]==3"></i> --> | |||
| </div> | |||
| <div class="one wide column text center" style="width: 7.25% !important;"> | |||
| {{.Size | FileSize}} | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| {{.Type | AttachmentResourceType}} | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{$x:=.IsPrivate | AttachmentStatus}} | |||
| <span style="color: #fa8c16;" v-if="privates[{{$k}}]">{{$.i18n.Tr "home.show_private"}}</span> | |||
| <span style="color: #13c28d;" v-else="privates[{{$k}}]">{{$.i18n.Tr "org.settings.visibility.public"}}</span> | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{if .Uploader.Name}} | |||
| <a href="{{AppSubUrl}}/{{.Uploader.Name}}" title="{{.Uploader.Name}}"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/{{.Uploader.Name}}/-1"></a> | |||
| {{else}} | |||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| {{end}} | |||
| </div> | |||
| <div class="three wide column text center"> | |||
| {{.CreatedUnix | TimeSinceUnix1}} | |||
| </div> | |||
| <div class="four wide column text right"> | |||
| <!-- <el-button type="text">下载</el-button> | |||
| </div> | |||
| <div class="one wide column text center" style="width: 7.25% !important;"> | |||
| {{.Size | FileSize}} | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| {{.Type | AttachmentResourceType}} | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{$x:=.IsPrivate | AttachmentStatus}} | |||
| <span style="color: #fa8c16;" v-if="privates[{{$k}}]">{{$.i18n.Tr "home.show_private"}}</span> | |||
| <span style="color: #13c28d;" | |||
| v-else="privates[{{$k}}]">{{$.i18n.Tr "org.settings.visibility.public"}}</span> | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{if .Uploader.Name}} | |||
| <a href="{{AppSubUrl}}/{{.Uploader.Name}}" title="{{.Uploader.Name}}"><img class="ui avatar image" | |||
| src="{{AppSubUrl}}/user/avatar/{{.Uploader.Name}}/-1"></a> | |||
| {{else}} | |||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| {{end}} | |||
| </div> | |||
| <div class="three wide column text center"> | |||
| {{.CreatedUnix | TimeSinceUnix1}} | |||
| </div> | |||
| <div class="four wide column text right"> | |||
| <!-- <el-button type="text">下载</el-button> | |||
| <el-button type="text">预览</el-button> | |||
| <el-button type="text">标注</el-button> | |||
| <el-button type="text"> | |||
| @@ -258,77 +298,81 @@ | |||
| <el-button slot="reference" type="text"><i class="ri-more-line"></i></el-button> | |||
| </el-popover> | |||
| </el-button> --> | |||
| <div class="ui compact buttons"> | |||
| <a class="ui basic blue button" href="{{.DownloadURL}}">{{$.i18n.Tr "dataset.download"}}</a> | |||
| {{if eq .DecompressState 1}} | |||
| <a class="ui basic blue button" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{$.i18n.Tr "preview"}}</a> | |||
| {{end}} | |||
| {{if and (.CanDel) (not $.Repository.IsPrivate)}} | |||
| <span class="ui basic blue button" style="color: #13c28d !important;" @click="setPrivate('{{.UUID}}',false,{{$k}})" v-if="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_public"}}</span> | |||
| <span class="ui basic blue button" style="color: #fa8c16 !important;" @click="setPrivate('{{.UUID}}',true,{{$k}})" v-else="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_private"}}</span> | |||
| {{end}} | |||
| <!-- {{if $.CanRead}} | |||
| <div class="ui compact buttons"> | |||
| <a class="ui basic blue button" href="{{.DownloadURL}}">{{$.i18n.Tr "dataset.download"}}</a> | |||
| {{if eq .DecompressState 1}} | |||
| <a class="ui basic blue button" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" | |||
| data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{$.i18n.Tr "preview"}}</a> | |||
| {{end}} | |||
| {{if and (.CanDel) (not $.Repository.IsPrivate)}} | |||
| <span class="ui basic blue button" style="color: #13c28d !important;" | |||
| @click="setPrivate('{{.UUID}}',false,{{$k}})" | |||
| v-if="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_public"}}</span> | |||
| <span class="ui basic blue button" style="color: #fa8c16 !important;" | |||
| @click="setPrivate('{{.UUID}}',true,{{$k}})" | |||
| v-else="privates[{{$k}}]">{{$.i18n.Tr "dataset.set_private"}}</span> | |||
| {{end}} | |||
| <!-- {{if $.CanRead}} | |||
| <a class="ui basic blue button" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'>标注</a> | |||
| {{else}} | |||
| <a class="ui basic disabled button">标注</a> | |||
| {{end}} --> | |||
| <a class="ui basic blue button"> | |||
| <el-dropdown size="medium"> | |||
| <span class="el-dropdown-link"> | |||
| {{$.i18n.Tr "repo.more"}}<i class="el-icon-arrow-down el-icon--right"></i> | |||
| </span> | |||
| <el-dropdown-menu slot="dropdown"> | |||
| <el-dropdown-item class="clipboard" data-clipboard-text="{{.DownloadURL}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_url"}}</el-dropdown-item> | |||
| <!-- <el-dropdown-item class="clipboard" data-clipboard-text="{{.Md5}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_md5"}}</el-dropdown-item>--> | |||
| {{if and ($.CanWrite) (eq .DecompressState 1) }} | |||
| <el-dropdown-item @click.native="gotoAnnotate('{{$.RepoLink}}','{{.UUID}}',{{.Type}})">{{$.i18n.Tr "dataset.annotation"}}</el-dropdown-item> | |||
| {{end}} | |||
| {{if .CanDel}} | |||
| <el-dropdown-item @click.native="gotoDatasetEidt('{{$.RepoLink}}',{{.ID}})">{{$.i18n.Tr "dataset.modify_description"}}</el-dropdown-item> | |||
| <el-dropdown-item style="color: red;" @click.native="delDataset('{{.UUID}}')">{{$.i18n.Tr "dataset.delete"}}</el-dropdown-item> | |||
| {{end}} | |||
| </el-dropdown-menu> | |||
| </el-dropdown> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| <a class="ui basic blue button"> | |||
| <el-dropdown size="medium"> | |||
| <span class="el-dropdown-link"> | |||
| {{$.i18n.Tr "repo.more"}}<i class="el-icon-arrow-down el-icon--right"></i> | |||
| </span> | |||
| <el-dropdown-menu slot="dropdown"> | |||
| <el-dropdown-item @click.native="copyUrl('{{.DownloadURL}}')">{{$.i18n.Tr "dataset.copy_url"}} | |||
| </el-dropdown-item> | |||
| <!-- <el-dropdown-item class="clipboard" data-clipboard-text="{{.Md5}}" data-clipboard-action="copy">{{$.i18n.Tr "dataset.copy_md5"}}</el-dropdown-item>--> | |||
| {{if and ($.CanWrite) (eq .DecompressState 1) }} | |||
| <el-dropdown-item @click.native="gotoAnnotate('{{$.RepoLink}}','{{.UUID}}',{{.Type}})"> | |||
| {{$.i18n.Tr "dataset.annotation"}}</el-dropdown-item> | |||
| {{end}} | |||
| {{if .CanDel}} | |||
| <el-dropdown-item @click.native="gotoDatasetEidt('{{$.RepoLink}}',{{.ID}})"> | |||
| {{$.i18n.Tr "dataset.modify_description"}}</el-dropdown-item> | |||
| <el-dropdown-item style="color: red;" @click.native="delDataset('{{.UUID}}')"> | |||
| {{$.i18n.Tr "dataset.delete"}}</el-dropdown-item> | |||
| {{end}} | |||
| </el-dropdown-menu> | |||
| </el-dropdown> | |||
| </a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div id="app" style="margin-top: 2rem;"> | |||
| <div class="center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-sizes="[10]" | |||
| :page-size="10" | |||
| layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| </el-pagination> | |||
| <el-pagination background @current-change="handleCurrentChange" :current-page="page" :page-sizes="[10]" | |||
| :page-size="10" layout="total, sizes, prev, pager, next, jumper" :total="{{.Page.Paginater.Total}}"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| {{else}} | |||
| <div class="ui placeholder segment bgtask-none"> | |||
| <div class="ui icon header bgtask-header-pic"></div> | |||
| <div class="bgtask-content-header">{{.i18n.Tr "dataset.dataset_no_create"}}</div> | |||
| {{if $.CanWrite}} | |||
| <a class="ui green button" href="{{.RepoLink}}/datasets/create">{{.i18n.Tr "dataset.create_new_dataset"}}</a> | |||
| {{end}} | |||
| <div class="bgtask-content"> | |||
| <div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_explain"}}</div> | |||
| <div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_instructions_for_use"}}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{.i18n.Tr "dataset.dataset_camp_course"}}</a></div> | |||
| </div> | |||
| <div class="ui icon header bgtask-header-pic"></div> | |||
| <div class="bgtask-content-header">{{.i18n.Tr "dataset.dataset_no_create"}}</div> | |||
| {{if $.CanWrite}} | |||
| <a class="ui green button" href="{{.RepoLink}}/datasets/create">{{.i18n.Tr "dataset.create_new_dataset"}}</a> | |||
| {{end}} | |||
| <div class="bgtask-content"> | |||
| <div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_explain"}}</div> | |||
| <div class="bgtask-content-txt">{{.i18n.Tr "dataset.dataset_instructions_for_use"}}<a | |||
| href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{.i18n.Tr "dataset.dataset_camp_course"}}</a></div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| @@ -343,4 +387,4 @@ | |||
| </div> | |||
| {{template "base/delete_modal_actions" .}} | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| {{template "base/footer" .}} | |||
| @@ -2,20 +2,23 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .label_after::after{ | |||
| .label_after::after { | |||
| margin: -.2em 0 0 .2em; | |||
| content: '\00a0'; | |||
| } | |||
| .selectcloudbrain .active.item{ | |||
| } | |||
| .selectcloudbrain .active.item { | |||
| color: #0087f5 !important; | |||
| border: 1px solid #0087f5; | |||
| margin: -1px; | |||
| background: #FFF !important; | |||
| } | |||
| #deletemodel { | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| /* 弹窗 */ | |||
| #mask { | |||
| @@ -73,28 +76,33 @@ | |||
| } | |||
| @-webkit-keyframes sk-stretchdelay { | |||
| 0%, | |||
| 40%, | |||
| 100% { | |||
| -webkit-transform: scaleY(0.4) | |||
| } | |||
| 20% { | |||
| -webkit-transform: scaleY(1.0) | |||
| } | |||
| } | |||
| @keyframes sk-stretchdelay { | |||
| 0%, | |||
| 40%, | |||
| 100% { | |||
| transform: scaleY(0.4); | |||
| -webkit-transform: scaleY(0.4); | |||
| } | |||
| 20% { | |||
| transform: scaleY(1.0); | |||
| -webkit-transform: scaleY(1.0); | |||
| } | |||
| } | |||
| /* 消息框 */ | |||
| .alert { | |||
| @@ -137,6 +145,7 @@ | |||
| width: calc(100% - 260px); | |||
| box-sizing: border-box; | |||
| } | |||
| /* 弹窗 (background) */ | |||
| #imageModal { | |||
| @@ -151,6 +160,7 @@ | |||
| background-color: rgb(0, 0, 0); | |||
| background-color: rgba(0, 0, 0, 0.4); | |||
| } | |||
| /* 弹窗内容 */ | |||
| .modal-content { | |||
| @@ -160,6 +170,7 @@ | |||
| border: 1px solid #888; | |||
| width: 30%; | |||
| } | |||
| /* 关闭按钮 */ | |||
| .close { | |||
| @@ -184,12 +195,12 @@ | |||
| cursor: pointer; | |||
| pointer-events: none; | |||
| } | |||
| .time-show{ | |||
| .time-show { | |||
| font-size: 10px; | |||
| margin-top: 0.4rem; | |||
| display: inline-block; | |||
| } | |||
| </style> | |||
| <!-- 弹窗 --> | |||
| @@ -208,49 +219,56 @@ | |||
| {{template "repo/header" .}} | |||
| {{template "base/alert" .}} | |||
| <!-- 提示框 --> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" data-debug-again="{{$.i18n.Tr "repo.debug_again"}}"></div> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" | |||
| data-debug-again="{{$.i18n.Tr "repo.debug_again"}}"></div> | |||
| <!-- 列表容器 --> | |||
| <div class="ui container"> | |||
| <div class="ui two column stackable grid"> | |||
| <div class="column"> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="active item" href="{{.RepoLink}}/debugjob?debugListType=all">{{$.i18n.Tr "repo.modelarts.notebook"}}</a> | |||
| <a class="item" href="{{.RepoLink}}/modelarts/train-job">{{$.i18n.Tr "repo.modelarts.train_job"}}</a> | |||
| <a class="item" href="{{.RepoLink}}/modelarts/inference-job">{{$.i18n.Tr "repo.modelarts.infer_job"}}</a> | |||
| <a class="item" href="{{.RepoLink}}/cloudbrain/benchmark">{{$.i18n.Tr "repo.modelarts.evaluate_job"}}</a> | |||
| </div> | |||
| <div class="column"> | |||
| <div class="ui blue small menu compact selectcloudbrain"> | |||
| <a class="active item" | |||
| href="{{.RepoLink}}/debugjob?debugListType=all">{{$.i18n.Tr "repo.modelarts.notebook"}}</a> | |||
| <a class="item" | |||
| href="{{.RepoLink}}/modelarts/train-job">{{$.i18n.Tr "repo.modelarts.train_job"}}</a> | |||
| <a class="item" | |||
| href="{{.RepoLink}}/modelarts/inference-job">{{$.i18n.Tr "repo.modelarts.infer_job"}}</a> | |||
| <a class="item" | |||
| href="{{.RepoLink}}/cloudbrain/benchmark">{{$.i18n.Tr "repo.modelarts.evaluate_job"}}</a> | |||
| </div> | |||
| <div class="column right aligned"> | |||
| <div class="ui selection dropdown" style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| {{svg "octicon-server" 16}} | |||
| <div class="default text" style="color: rgba(0,0,0,.87);"></div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||
| <div class="item" data-value="CPU/GPU">CPU/GPU</div> | |||
| <div class="item" data-value="NPU">NPU</div> | |||
| </div> | |||
| </div> | |||
| <div class="column right aligned"> | |||
| <div class="ui selection dropdown" | |||
| style="min-width: 10em;min-height:2.6em;border-radius: .28571429rem;margin-right: 1em;padding: .67em 3.2em .7em 1em;"> | |||
| {{svg "octicon-server" 16}} | |||
| <div class="default text" style="color: rgba(0,0,0,.87);"></div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu"> | |||
| <div class="item" data-value="all">{{$.i18n.Tr "repo.gpu_type_all"}}</div> | |||
| <div class="item" data-value="CPU/GPU">CPU/GPU</div> | |||
| <div class="item" data-value="NPU">NPU</div> | |||
| </div> | |||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||
| <a class="ui green button" href="{{.RepoLink}}/cloudbrain/create">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | |||
| {{else}} | |||
| <a class="ui disabled button">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | |||
| {{end}} | |||
| </div> | |||
| {{if .Permission.CanWrite $.UnitTypeCloudBrain}} | |||
| <a class="ui green button" | |||
| href="{{.RepoLink}}/cloudbrain/create">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | |||
| {{else}} | |||
| <a class="ui disabled button">{{$.i18n.Tr "repo.modelarts.train_job.new_debug"}}</a> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| {{if eq 0 (len .Tasks)}} | |||
| <div class="ui placeholder segment bgtask-none"> | |||
| <div class="ui icon header bgtask-header-pic"></div> | |||
| <div class="bgtask-content-header">{{$.i18n.Tr "repo.debug_task_not_created"}}</div> | |||
| <div class="bgtask-content"> | |||
| {{if $.RepoIsEmpty}} | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div> | |||
| {{end}} | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.debug_task_running_limit"}}</div> | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.dataset_desc"}}</div> | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" | Safe}}</div> | |||
| </div> | |||
| <div class="ui icon header bgtask-header-pic"></div> | |||
| <div class="bgtask-content-header">{{$.i18n.Tr "repo.debug_task_not_created"}}</div> | |||
| <div class="bgtask-content"> | |||
| {{if $.RepoIsEmpty}} | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.repo_not_initialized" .RepoLink | Safe}}</div> | |||
| {{end}} | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.debug_task_running_limit"}}</div> | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.dataset_desc"}}</div> | |||
| <div class="bgtask-content-txt">{{$.i18n.Tr "repo.platform_instructions" | Safe}}</div> | |||
| </div> | |||
| </div> | |||
| {{else}} | |||
| <!-- 中下列表展示区 --> | |||
| @@ -287,29 +305,40 @@ | |||
| <div class="row"> | |||
| <!-- 任务名 --> | |||
| <div class="four wide column"> | |||
| <a class="title" href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.Cloudbrain.ID}}{{end}}' title="{{.JobName}}" style="font-size: 14px;"> | |||
| <span class="fitted text_over" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href='{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}{{else}}{{$.RepoLink}}/modelarts/notebook/{{.Cloudbrain.ID}}{{end}}' | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted text_over" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| <!--任务状态 --> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}"> | |||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <!--任务状态 --> | |||
| <span class="job-status" id="{{.Cloudbrain.ID}}" | |||
| data-repopath="{{$.RepoRelPath}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}" | |||
| data-jobid="{{.Cloudbrain.ID}}" data-resource="{{.ComputeResource}}"> | |||
| <span><i id="{{.Cloudbrain.ID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{.Cloudbrain.ID}}-text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| <!-- 任务创建时间 --> | |||
| <span style="font-size: 12px;margin-left: 0.4rem;" class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | |||
| <span style="font-size: 12px;margin-left: 0.4rem;" | |||
| class="">{{TimeSinceUnix .Cloudbrain.CreatedUnix $.Lang}}</span> | |||
| </div> | |||
| <div class="two wide column text center"> | |||
| <!-- 任务计算资源 --> | |||
| <span style="font-size: 12px;margin-left: 0.4rem;" class="">{{.ComputeResource}}</span> | |||
| <!-- 任务计算资源 --> | |||
| <span style="font-size: 12px;margin-left: 0.4rem;" | |||
| class="">{{.ComputeResource}}</span> | |||
| </div> | |||
| <div class="one wide column text center"> | |||
| {{if .User.Name}} | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| <a href="{{AppSubUrl}}/{{.User.Name}}" title="{{.User.Name}}"><img | |||
| class="ui avatar image" src="{{.User.RelAvatarLink}}"></a> | |||
| {{else}} | |||
| <a title="Ghost"><img class="ui avatar image" src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| <a title="Ghost"><img class="ui avatar image" | |||
| src="{{AppSubUrl}}/user/avatar/Ghost/-1"></a> | |||
| {{end}} | |||
| </div> | |||
| <div class="five wide column text center"> | |||
| @@ -323,79 +352,103 @@ | |||
| <form id="debugAgainForm-{{.Cloudbrain.ID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDebug}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.Cloudbrain.ID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{.Cloudbrain.ID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{.Cloudbrain.ID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{.Cloudbrain.ID}}" data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/' data-linkpath='{{$.Link}}'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{.Cloudbrain.ID}}" | |||
| class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' | |||
| data-jobid="{{.Cloudbrain.ID}}" | |||
| data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| <a id="ai-debug-{{.Cloudbrain.ID}}" | |||
| class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' | |||
| data-jobid="{{.Cloudbrain.ID}}" | |||
| data-repopath='{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/' | |||
| data-linkpath='{{$.Link}}'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| {{else}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| {{end}} | |||
| </form> | |||
| <!-- 停止 --> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| <form id="stopForm-{{.Cloudbrain.ID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-stop-{{.Cloudbrain.ID}}" class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" data-jobid="{{.Cloudbrain.ID}}"> | |||
| <a id="ai-stop-{{.Cloudbrain.ID}}" | |||
| class='ui basic ai_stop {{if eq .Status "STOPPED" "FAILED" "START_FAILED" "STOPPING" "CREATING" "STARTING" "SUCCEEDED"}}disabled {{else}}blue {{end}}button' | |||
| data-repopath="{{$.RepoLink}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/stop" | |||
| data-jobid="{{.Cloudbrain.ID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{else}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| <a class="ui basic disabled button"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| <!-- 删除 --> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" method="post"> | |||
| <form id="delForm-{{.Cloudbrain.ID}}" | |||
| action="{{if eq .ComputeResource "CPU/GPU"}}{{$.RepoLink}}/cloudbrain{{else}}{{$.RepoLink}}/modelarts/notebook{{end}}/{{.Cloudbrain.ID}}/del" | |||
| method="post"> | |||
| <input type="hidden" name="debugListType" value="{{$.ListType}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if .CanDel}} | |||
| <a id="ai-delete-{{.Cloudbrain.ID}}" class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' style="border-radius: .28571429rem;"> | |||
| <a id="ai-delete-{{.Cloudbrain.ID}}" | |||
| class='ui basic ai_delete {{if eq .Status "STOPPED" "FAILED" "START_FAILED"}}blue {{else}}disabled {{end}}button' | |||
| style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{else}} | |||
| <a class="ui basic button disabled" style="border-radius: .28571429rem;"> | |||
| <a class="ui basic button disabled" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| {{end}} | |||
| </form> | |||
| </div> | |||
| <div class="ui compact buttons" style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | |||
| <div class="ui dropdown" id="model_more" style="padding: .58928571em 1.125em .58928571em;"> | |||
| <div class="ui compact buttons" | |||
| style="{{if eq .ComputeResource "CPU/GPU"}} visibility: visible {{else}} visibility: hidden{{end}}"> | |||
| <div class="ui dropdown" id="model_more" | |||
| style="padding: .58928571em 1.125em .58928571em;"> | |||
| <div class="text">{{$.i18n.Tr "repo.more"}}</div> | |||
| <i class="dropdown icon"></i> | |||
| <div class="menu" style="right: auto;"> | |||
| <div class="item" style="padding: 0 !important;"> | |||
| {{if .CanDebug}} | |||
| <a id="model-image-{{.Cloudbrain.ID}}" class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button' href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image">{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| <a id="model-image-{{.Cloudbrain.ID}}" | |||
| class='imageBtn ui basic {{if ne .Status "RUNNING"}}disabled {{else}}blue {{end}}button' | |||
| href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/commit_image">{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| {{else}} | |||
| <a class="imageBtn ui basic disabled button">{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| <a | |||
| class="imageBtn ui basic disabled button">{{$.i18n.Tr "repo.submit_image"}}</a> | |||
| {{end}} | |||
| </div> | |||
| <div class="item" style="padding: 0 !important;"> | |||
| <!-- 模型下载 --> | |||
| <!-- 模型下载 --> | |||
| {{if .CanDebug}} | |||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/models" target="_blank">{{$.i18n.Tr "repo.download"}}</a> | |||
| <a class="ui basic blue button" | |||
| href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/models" | |||
| target="_blank">{{$.i18n.Tr "repo.download"}}</a> | |||
| {{else}} | |||
| <a class="ui basic disabled button">{{$.i18n.Tr "repo.download"}}</a> | |||
| <a | |||
| class="ui basic disabled button">{{$.i18n.Tr "repo.download"}}</a> | |||
| {{end}} | |||
| </div> | |||
| {{if and (ne .JobType "DEBUG") (eq .Cloudbrain.Type 0)}} | |||
| <div class="item" style="padding: 0 !important;"> | |||
| <a class="ui basic blue button" href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||
| <a class="ui basic blue button" | |||
| href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" | |||
| target="_blank"> | |||
| 评分 | |||
| </a> | |||
| </div> | |||
| @@ -405,20 +458,15 @@ | |||
| </div> | |||
| </div> | |||
| <!-- 镜像列表弹窗 --> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| <div id="app" style="margin-top: 2rem;"> | |||
| <div class="center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-sizes="[10]" | |||
| :page-size="10" | |||
| layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| <el-pagination background @current-change="handleCurrentChange" :current-page="page" | |||
| :page-sizes="[10]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| @@ -457,42 +505,41 @@ | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| // 调试和评分新开窗口 | |||
| const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | |||
| let url={{.RepoLink}} | |||
| let redirect_to = {{$.Link}} | |||
| let getParam=getQueryVariable('debugListType') | |||
| const { AppSubUrl, StaticUrlPrefix, csrf } = window.config; | |||
| let url = {{.RepoLink }} | |||
| let redirect_to = {{ $.Link }} | |||
| let getParam = getQueryVariable('debugListType') | |||
| let dropdownValue = ['all','',false].includes(getParam)? '{{$.i18n.Tr "repo.gpu_type_all"}}' : getParam | |||
| let dropdownValue = ['all', '', false].includes(getParam) ? '{{$.i18n.Tr "repo.gpu_type_all"}}' : getParam | |||
| // localStorage.setItem('all',location.href) | |||
| function getQueryVariable(variable) | |||
| { | |||
| function getQueryVariable(variable) { | |||
| let query = window.location.search.substring(1); | |||
| let vars = query.split("&"); | |||
| for (let i=0;i<vars.length;i++) { | |||
| let pair = vars[i].split("="); | |||
| if(pair[0] == variable){return pair[1];} | |||
| for (let i = 0; i < vars.length; i++) { | |||
| let pair = vars[i].split("="); | |||
| if (pair[0] == variable) { return pair[1]; } | |||
| } | |||
| return(false); | |||
| return (false); | |||
| } | |||
| $(document).ready(function(){ | |||
| dropdownValue = dropdownValue==="CPU%2FGPU"? 'CPU/GPU' : dropdownValue | |||
| $(document).ready(function () { | |||
| dropdownValue = dropdownValue === "CPU%2FGPU" ? 'CPU/GPU' : dropdownValue | |||
| $('.default.text').text(dropdownValue) | |||
| $('.ui.dropdown') | |||
| .dropdown({ | |||
| action: 'hide', | |||
| }) | |||
| .dropdown({ | |||
| action: 'hide', | |||
| }) | |||
| $('.ui.selection.dropdown').dropdown({ | |||
| onChange:function(value){ | |||
| onChange: function (value) { | |||
| location.href = `${url}/debugjob?debugListType=${value}` | |||
| } | |||
| }) | |||
| $('.message .close') | |||
| .on('click', function() { | |||
| $(this) | |||
| .closest('.message') | |||
| .transition('fade') | |||
| }) | |||
| .on('click', function () { | |||
| $(this) | |||
| .closest('.message') | |||
| .transition('fade') | |||
| }) | |||
| }) | |||
| </script> | |||
| </script> | |||
| @@ -1,102 +1,114 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .repository.file.list #repo-desc { | |||
| font-size: 1.0em; | |||
| margin-bottom: 1.0rem; | |||
| } | |||
| #contributorInfo > a:nth-child(n+26){ | |||
| display:none; | |||
| } | |||
| #contributorInfo > a{ | |||
| width: 2.0em; | |||
| float: left; | |||
| margin: .25em; | |||
| } | |||
| .edit-link{ | |||
| vertical-align: top; | |||
| display: inline-block; | |||
| overflow: hidden; | |||
| word-break: keep-all; | |||
| white-space: nowrap; | |||
| text-overflow: ellipsis; | |||
| width: 16.5em; | |||
| } | |||
| #contributorInfo > a.circular{ | |||
| height: 2.0em; | |||
| padding: 0; | |||
| overflow: hidden; | |||
| letter-spacing:1.0em; | |||
| text-indent: 0.6em; | |||
| line-height: 2.0em; | |||
| text-transform:capitalize; | |||
| color: #FFF; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+1){ | |||
| background-color: #4ccdec; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+2){ | |||
| background-color: #e0b265; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+3){ | |||
| background-color: #d884b7; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+4){ | |||
| background-color: #8c6bdc; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+5){ | |||
| background-color: #3cb99f; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+6){ | |||
| background-color: #6995b9; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+7){ | |||
| background-color: #ab91a7; | |||
| } | |||
| #contributorInfo > a.circular:nth-child(9n+8){ | |||
| background-color: #bfd0aa; | |||
| } | |||
| .vue_menu { | |||
| cursor: auto; | |||
| position: absolute; | |||
| outline: none; | |||
| top: 100%; | |||
| margin: 0em; | |||
| padding: 0em 0em; | |||
| background: #fff; | |||
| font-size: 1em; | |||
| text-shadow: none; | |||
| text-align: left; | |||
| /* -webkit-box-shadow: 0px 2px 3px 0px rgb(34 36 38 / 15%); */ | |||
| box-shadow: 0px 2px 3px 0px rgba(34, 36, 38, 0.15); | |||
| border: 1px solid rgba(34,36,38,0.15); | |||
| border-radius: 0.28571429rem; | |||
| -webkit-transition: opacity 0.1s ease; | |||
| transition: opacity 0.1s ease; | |||
| z-index: 11; | |||
| will-change: transform, opacity; | |||
| width: 100% !important; | |||
| -webkit-animation-iteration-count: 1; | |||
| animation-iteration-count: 1; | |||
| -webkit-animation-duration: 300ms; | |||
| animation-duration: 300ms; | |||
| -webkit-animation-timing-function: ease; | |||
| animation-timing-function: ease; | |||
| -webkit-animation-fill-mode: both; | |||
| animation-fill-mode: both; | |||
| } | |||
| .repository.file.list #repo-desc { | |||
| font-size: 1.0em; | |||
| margin-bottom: 1.0rem; | |||
| } | |||
| #contributorInfo>a:nth-child(n+26) { | |||
| display: none; | |||
| } | |||
| #contributorInfo>a { | |||
| width: 2.0em; | |||
| float: left; | |||
| margin: .25em; | |||
| } | |||
| .edit-link { | |||
| vertical-align: top; | |||
| display: inline-block; | |||
| overflow: hidden; | |||
| word-break: keep-all; | |||
| white-space: nowrap; | |||
| text-overflow: ellipsis; | |||
| width: 16.5em; | |||
| } | |||
| #contributorInfo>a.circular { | |||
| height: 2.0em; | |||
| padding: 0; | |||
| overflow: hidden; | |||
| letter-spacing: 1.0em; | |||
| text-indent: 0.6em; | |||
| line-height: 2.0em; | |||
| text-transform: capitalize; | |||
| color: #FFF; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+1) { | |||
| background-color: #4ccdec; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+2) { | |||
| background-color: #e0b265; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+3) { | |||
| background-color: #d884b7; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+4) { | |||
| background-color: #8c6bdc; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+5) { | |||
| background-color: #3cb99f; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+6) { | |||
| background-color: #6995b9; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+7) { | |||
| background-color: #ab91a7; | |||
| } | |||
| #contributorInfo>a.circular:nth-child(9n+8) { | |||
| background-color: #bfd0aa; | |||
| } | |||
| .vue_menu { | |||
| cursor: auto; | |||
| position: absolute; | |||
| outline: none; | |||
| top: 100%; | |||
| margin: 0em; | |||
| padding: 0em 0em; | |||
| background: #fff; | |||
| font-size: 1em; | |||
| text-shadow: none; | |||
| text-align: left; | |||
| /* -webkit-box-shadow: 0px 2px 3px 0px rgb(34 36 38 / 15%); */ | |||
| box-shadow: 0px 2px 3px 0px rgba(34, 36, 38, 0.15); | |||
| border: 1px solid rgba(34, 36, 38, 0.15); | |||
| border-radius: 0.28571429rem; | |||
| -webkit-transition: opacity 0.1s ease; | |||
| transition: opacity 0.1s ease; | |||
| z-index: 11; | |||
| will-change: transform, opacity; | |||
| width: 100% !important; | |||
| -webkit-animation-iteration-count: 1; | |||
| animation-iteration-count: 1; | |||
| -webkit-animation-duration: 300ms; | |||
| animation-duration: 300ms; | |||
| -webkit-animation-timing-function: ease; | |||
| animation-timing-function: ease; | |||
| -webkit-animation-fill-mode: both; | |||
| animation-fill-mode: both; | |||
| } | |||
| </style> | |||
| <div class="repository file list"> | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <div class="ui negative message" style="display: none;"> | |||
| </div> | |||
| {{template "base/alert" .}} | |||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}} | |||
| <!-- <div class="ui repo-topic-edit grid form segment error" id="topic_edit" style="display:none"> | |||
| <!-- <div class="ui repo-topic-edit grid form segment error" id="topic_edit" style="display:none"> | |||
| <div class="fourteen wide column"> | |||
| <div class="field"> | |||
| <div class="ui fluid multiple search selection dropdown"> | |||
| @@ -114,33 +126,33 @@ | |||
| </div> | |||
| </div> --> | |||
| {{end}} | |||
| <div class="hide" id="validate_prompt"> | |||
| <span id="count_prompt">{{.i18n.Tr "repo.topic.count_prompt"}}</span> | |||
| <span id="format_prompt">{{.i18n.Tr "repo.topic.format_prompt"}}</span> | |||
| </div> | |||
| {{end}} | |||
| <div class="hide" id="validate_prompt"> | |||
| <span id="count_prompt">{{.i18n.Tr "repo.topic.count_prompt"}}</span> | |||
| <span id="format_prompt">{{.i18n.Tr "repo.topic.format_prompt"}}</span> | |||
| </div> | |||
| <div class="ui repo-description stackable grid"> | |||
| {{if .RepoSearchEnabled}} | |||
| <div class="ui repo-search four wide column"> | |||
| <form class="ui form ignore-dirty" action="{{.RepoLink}}/search" method="get"> | |||
| <div class="field"> | |||
| <div class="ui action input"> | |||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}"> | |||
| <button class="ui icon button" type="submit"> | |||
| <i class="search icon"></i> | |||
| </button> | |||
| </div> | |||
| <div class="ui repo-search four wide column"> | |||
| <form class="ui form ignore-dirty" action="{{.RepoLink}}/search" method="get"> | |||
| <div class="field"> | |||
| <div class="ui action input"> | |||
| <input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "repo.search.search_repo"}}"> | |||
| <button class="ui icon button" type="submit"> | |||
| <i class="search icon"></i> | |||
| </button> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| {{if .Repository.IsArchived}} | |||
| <div class="ui warning message"> | |||
| {{.i18n.Tr "repo.archive.title"}} | |||
| </div> | |||
| <div class="ui warning message"> | |||
| {{.i18n.Tr "repo.archive.title"}} | |||
| </div> | |||
| {{end}} | |||
| {{template "repo/sub_menu" .}} | |||
| <div class="ui stackable secondary menu mobile--margin-between-items mobile--no-negative-margins"> | |||
| @@ -149,97 +161,122 @@ | |||
| {{ $l := Subtract $n 1}} | |||
| <!-- If home page, show new PR. If not, show breadcrumb --> | |||
| {{if eq $n 0}} | |||
| {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} | |||
| <div class="fitted item"> | |||
| <a href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button">{{if .PullRequestCtx.Allowed}}{{.i18n.Tr "repo.pulls.compare_changes"}}{{else}}{{.i18n.Tr "action.compare_branch"}}{{end}}</button> | |||
| </a> | |||
| {{if and .Repository.IsFork .PullRequestCtx.Allowed}} | |||
| {{if gt .FetchUpstreamCnt 0 }} | |||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" title="{{$.i18n.Tr (TrN $.i18n.Lang .FetchUpstreamCnt "repo.pulls.commits_count_1" "repo.pulls.commits_count_n") .FetchUpstreamCnt}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{else if lt .FetchUpstreamCnt 0}} | |||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" title="{{.i18n.Tr "repo.pulls.upstream_error"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{else}} | |||
| <a href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" title="{{.i18n.Tr "repo.pulls.upstream_up_to_date"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| {{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}} | |||
| <div class="fitted item"> | |||
| <a | |||
| href="{{.BaseRepo.Link}}/compare/{{.BaseRepo.DefaultBranch | EscapePound}}...{{if ne .Repository.Owner.Name .BaseRepo.Owner.Name}}{{.Repository.Owner.Name}}:{{end}}{{.BranchName | EscapePound}}"> | |||
| <button id="new-pull-request" | |||
| class="ui compact basic button">{{if .PullRequestCtx.Allowed}}{{.i18n.Tr "repo.pulls.compare_changes"}}{{else}}{{.i18n.Tr "action.compare_branch"}}{{end}}</button> | |||
| </a> | |||
| {{if and .Repository.IsFork .PullRequestCtx.Allowed}} | |||
| {{if gt .FetchUpstreamCnt 0 }} | |||
| <a | |||
| href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" | |||
| title="{{$.i18n.Tr (TrN $.i18n.Lang .FetchUpstreamCnt "repo.pulls.commits_count_1" "repo.pulls.commits_count_n") .FetchUpstreamCnt}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{else if lt .FetchUpstreamCnt 0}} | |||
| <a | |||
| href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{.BaseRepo.DefaultBranch | EscapePound}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" | |||
| title="{{.i18n.Tr "repo.pulls.upstream_error"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{else}} | |||
| <a | |||
| href="{{.Repository.Link}}/compare/{{.BranchName | EscapePound}}...{{.BaseRepo.Owner.Name}}:{{if .UpstreamSameBranchName}}{{.BranchName | EscapePound}}{{else}}{{.BaseRepo.DefaultBranch | EscapePound}}{{end}}"> | |||
| <button id="new-pull-request" class="ui compact basic button" | |||
| title="{{.i18n.Tr "repo.pulls.upstream_up_to_date"}}">{{.i18n.Tr "repo.pulls.fetch_upstream"}}</button> | |||
| </a> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| {{end}} | |||
| {{else}} | |||
| <div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section" href="{{.RepoLink}}/src/{{EscapePound .BranchNameSubURL}}" title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span class="divider">/</span>{{if eq $i $l}}<span class="active section" title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}<span class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}" title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div> | |||
| <div class="fitted item"><span class="ui breadcrumb repo-path"><a class="section" | |||
| href="{{.RepoLink}}/src/{{EscapePound .BranchNameSubURL}}" | |||
| title="{{.Repository.Name}}">{{EllipsisString .Repository.Name 30}}</a>{{range $i, $v := .TreeNames}}<span | |||
| class="divider">/</span>{{if eq $i $l}}<span class="active section" | |||
| title="{{$v}}">{{EllipsisString $v 30}}</span>{{else}}{{ $p := index $.Paths $i}}<span | |||
| class="section"><a href="{{EscapePound $.BranchLink}}/{{EscapePound $p}}" | |||
| title="{{$v}}">{{EllipsisString $v 30}}</a></span>{{end}}{{end}}</span></div> | |||
| {{end}} | |||
| <div class="right fitted item" id="file-buttons"> | |||
| <div class="ui tiny blue buttons"> | |||
| {{if .Repository.CanEnableEditor}} | |||
| {{if .CanAddFile}} | |||
| <a href="{{.RepoLink}}/_new/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" class="ui button"> | |||
| {{.i18n.Tr "repo.editor.new_file"}} | |||
| </a> | |||
| {{end}} | |||
| {{if .CanUploadFile}} | |||
| <a href="{{.RepoLink}}/_upload/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" class="ui button"> | |||
| {{.i18n.Tr "repo.editor.upload_file"}} | |||
| </a> | |||
| {{end}} | |||
| {{if .CanAddFile}} | |||
| <a href="{{.RepoLink}}/_new/{{EscapePound .BranchName}}/{{EscapePound .TreePath}}" | |||
| class="ui button"> | |||
| {{.i18n.Tr "repo.editor.new_file"}} | |||
| </a> | |||
| {{end}} | |||
| {{if .CanUploadFile}} | |||
| <a href="{{.RepoLink}}/_upload/{{EscapePound .BranchName}}/{{EscapePound .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/{{EscapePound .BranchNameSubURL}}/{{EscapePound .TreePath}}" class="ui button"> | |||
| {{.i18n.Tr "repo.file_history"}} | |||
| </a> | |||
| <a href="{{.RepoLink}}/commits/{{EscapePound .BranchNameSubURL}}/{{EscapePound .TreePath}}" | |||
| class="ui button"> | |||
| {{.i18n.Tr "repo.file_history"}} | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| <div class="fitted item"> | |||
| {{if eq $n 0}} | |||
| {{if .Repository.IsTemplate}} | |||
| <div class="ui tiny blue buttons"> | |||
| <a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button"> | |||
| {{.i18n.Tr "repo.use_template"}} | |||
| </a> | |||
| </div> | |||
| {{end}} | |||
| {{if .Repository.IsTemplate}} | |||
| <div class="ui tiny blue buttons"> | |||
| <a href="{{AppSubUrl}}/repo/create?template_id={{.Repository.ID}}" class="ui button"> | |||
| {{.i18n.Tr "repo.use_template"}} | |||
| </a> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| </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"> | |||
| {{if not $.DisableHTTP}} | |||
| <button class="ui basic clone button" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}"> | |||
| {{if UseHTTPS}}HTTPS{{else}}HTTP{{end}} | |||
| </button> | |||
| {{end}} | |||
| {{if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||
| <button class="ui basic clone button" id="repo-clone-ssh" data-link="{{.CloneLink.SSH}}"> | |||
| SSH | |||
| </button> | |||
| {{end}} | |||
| {{if not $.DisableHTTP}} | |||
| <input id="repo-clone-url" value="{{$.CloneLink.HTTPS}}" readonly> | |||
| {{else if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||
| <input id="repo-clone-url" value="{{$.CloneLink.SSH}}" readonly> | |||
| {{end}} | |||
| {{if or (not $.DisableHTTP) (and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH))}} | |||
| <button class="ui basic icon button poping up clipboard" 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"> | |||
| {{svg "octicon-clippy" 16}} | |||
| </button> | |||
| {{end}} | |||
| <div class="ui basic jump dropdown icon button poping up" data-content="{{.i18n.Tr "repo.download_archive"}}" data-variation="tiny inverted" data-position="top right"> | |||
| <i class="download icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip">{{svg "octicon-file-zip" 16}} ZIP</a> | |||
| <a class="item" href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz">{{svg "octicon-file-zip" 16}} TAR.GZ</a> | |||
| </div> | |||
| <div class="ui action tiny input" id="clone-panel"> | |||
| {{if not $.DisableHTTP}} | |||
| <button class="ui basic clone button" id="repo-clone-https" data-link="{{.CloneLink.HTTPS}}"> | |||
| {{if UseHTTPS}}HTTPS{{else}}HTTP{{end}} | |||
| </button> | |||
| {{end}} | |||
| {{if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||
| <button class="ui basic clone button" id="repo-clone-ssh" data-link="{{.CloneLink.SSH}}"> | |||
| SSH | |||
| </button> | |||
| {{end}} | |||
| {{if not $.DisableHTTP}} | |||
| <input id="repo-clone-url" value="{{$.CloneLink.HTTPS}}" readonly> | |||
| {{else if and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH)}} | |||
| <input id="repo-clone-url" value="{{$.CloneLink.SSH}}" readonly> | |||
| {{end}} | |||
| {{if or (not $.DisableHTTP) (and (not $.DisableSSH) (or $.IsSigned $.ExposeAnonSSH))}} | |||
| <button class="ui basic icon button poping up clipboard" 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"> | |||
| {{svg "octicon-clippy" 16}} | |||
| </button> | |||
| {{end}} | |||
| <div class="ui basic jump dropdown icon button poping up" | |||
| data-content="{{.i18n.Tr "repo.download_archive"}}" data-variation="tiny inverted" | |||
| data-position="top right"> | |||
| <i class="download icon"></i> | |||
| <div class="menu"> | |||
| <a class="item" | |||
| href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.zip">{{svg "octicon-file-zip" 16}} ZIP</a> | |||
| <a class="item" | |||
| href="{{$.RepoLink}}/archive/{{EscapePound $.BranchName}}.tar.gz">{{svg "octicon-file-zip" 16}} TAR.GZ</a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| @@ -247,22 +284,24 @@ | |||
| <div class="ui mobile reversed stackable grid"> | |||
| <div class="ui ten wide tablet twelve wide computer column"> | |||
| {{if .IsViewFile}} | |||
| {{template "repo/view_file" .}} | |||
| {{template "repo/view_file" .}} | |||
| {{else if .IsBlame}} | |||
| {{template "repo/blame" .}} | |||
| {{template "repo/blame" .}} | |||
| {{else}} | |||
| {{template "repo/view_list" .}} | |||
| {{template "repo/view_list" .}} | |||
| {{end}} | |||
| </div> | |||
| <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> | |||
| <input type="hidden" id="edit-alias" value="{{.Repository.Alias}}"> | |||
| <div id="repo-desc" data-IsAdmin="{{.Permission.IsAdmin}}" | |||
| data-IsArchived="{{.Repository.IsArchived}}"> | |||
| <h4 id="about-desc" class="ui header">简介</h4> | |||
| <input type="hidden" id="edit-alias" value="{{.Repository.Alias}}"> | |||
| <p> | |||
| {{if .Repository.DescriptionHTML}} | |||
| <span class="description" style="word-break:break-all">{{.Repository.DescriptionHTML}}</span> | |||
| <span class="description" | |||
| style="word-break:break-all">{{.Repository.DescriptionHTML}}</span> | |||
| {{else}} | |||
| <span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span> | |||
| <span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span> | |||
| {{end}} | |||
| </p> | |||
| @@ -274,7 +313,8 @@ | |||
| {{if .Repository.Website}} | |||
| <p class="ui"> | |||
| <i class="gray linkify icon"></i> | |||
| <a class="link edit-link" target="_blank" title="{{.Repository.Website}}" href="{{.Repository.Website}}">{{.Repository.Website}}</a> | |||
| <a class="link edit-link" target="_blank" title="{{.Repository.Website}}" | |||
| href="{{.Repository.Website}}">{{.Repository.Website}}</a> | |||
| </p> | |||
| {{end}} | |||
| @@ -284,11 +324,13 @@ | |||
| <div id="repo-topics1" style="flex: 1;"> | |||
| {{range .Topics}} | |||
| <a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=">{{.Name}}</a> | |||
| <a class="ui repo-topic small label topic" | |||
| href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=">{{.Name}}</a> | |||
| {{end}} | |||
| </div> | |||
| <div> | |||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<i id="manage_topic" style="cursor: pointer;" class="plus icon"></i>{{end}} | |||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<i id="manage_topic" | |||
| style="cursor: pointer;" class="plus icon"></i>{{end}} | |||
| </div> | |||
| <div id="topic_edit" class="vue_menu" style="display:none"> | |||
| <div id="topic_edit1"> | |||
| @@ -302,7 +344,7 @@ | |||
| <p class="ui"> | |||
| <i class="grey code icon"></i> | |||
| {{range .LanguageStats}} | |||
| {{.Language}} | |||
| {{.Language}} | |||
| {{end}} | |||
| </p> | |||
| @@ -311,7 +353,7 @@ | |||
| {{if .LICENSE}} | |||
| <p class="ui"> | |||
| <i class="grey clone icon"></i> | |||
| {{.LICENSE}} | |||
| {{.LICENSE}} | |||
| </p> | |||
| {{end}} | |||
| @@ -326,19 +368,22 @@ | |||
| {{else}} | |||
| <strong>贡献者 ({{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?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部 {{svg "octicon-chevron-right" 16}}</a> | |||
| <a class="membersmore text grey" | |||
| href="{{.RepoLink}}/contributors?type={{if .IsViewBranch}}branch{{else}}tag{{end}}&name={{.BranchName}}">全部 | |||
| {{svg "octicon-chevron-right" 16}}</a> | |||
| </div> | |||
| </h4> | |||
| <div class="ui members" id="contributorInfo"> | |||
| {{range .ContributorInfo}} | |||
| {{if .UserInfo}} | |||
| <a href="{{AppSubUrl}}/{{.UserInfo.Name}}"><img class="ui avatar image" src="{{.UserInfo.RelAvatarLink}}"></a> | |||
| {{else if .Email}} | |||
| <a href="mailto:{{.Email}}" class="circular ui button">{{.Email}}</a> | |||
| {{end}} | |||
| {{if .UserInfo}} | |||
| <a href="{{AppSubUrl}}/{{.UserInfo.Name}}"><img class="ui avatar image" | |||
| src="{{.UserInfo.RelAvatarLink}}"></a> | |||
| {{else if .Email}} | |||
| <a href="mailto:{{.Email}}" class="circular ui button">{{.Email}}</a> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| @@ -357,4 +402,4 @@ | |||
| // }); | |||
| // }); | |||
| </script> | |||
| {{template "base/footer" .}} | |||
| {{template "base/footer" .}} | |||
| @@ -1,179 +1,213 @@ | |||
| {{template "base/head" .}} | |||
| <style> | |||
| .according-panel-heading{ | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content{ | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border{ | |||
| border:1px solid #cce2ff; | |||
| } | |||
| .padding0{ | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad{ | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin{ | |||
| margin:10px 5px ; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 460px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .info_text { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| font-size: 12px; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content{ | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 450px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .text-span-new { | |||
| width: 800px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| height: 20%; | |||
| word-break: break-all; | |||
| } | |||
| .redo-color{ | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child){ | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none!important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80{ | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according{ | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| .according-panel-heading { | |||
| box-sizing: border-box; | |||
| padding: 8px 16px; | |||
| color: #252b3a; | |||
| background-color: #f2f5fc; | |||
| line-height: 1.5; | |||
| cursor: pointer; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| } | |||
| .accordion-panel-title { | |||
| margin-top: 0; | |||
| margin-bottom: 0; | |||
| color: #252b3a; | |||
| } | |||
| .accordion-panel-title-content { | |||
| vertical-align: middle; | |||
| display: inline-block; | |||
| width: calc(100% - 32px); | |||
| cursor: default; | |||
| } | |||
| .acc-margin-bottom { | |||
| margin-bottom: 5px; | |||
| } | |||
| .title_text { | |||
| font-size: 12px; | |||
| } | |||
| .ac-display-inblock { | |||
| display: inline-block; | |||
| } | |||
| .cti-mgRight-sm { | |||
| margin-right: 8px; | |||
| } | |||
| .ac-text-normal { | |||
| font-size: 14px; | |||
| color: #575d6c; | |||
| } | |||
| .uc-accordionTitle-black { | |||
| color: #333; | |||
| } | |||
| .accordion-border { | |||
| border: 1px solid #cce2ff; | |||
| } | |||
| .padding0 { | |||
| padding: 0 !important; | |||
| } | |||
| .content-pad { | |||
| padding: 15px 35px; | |||
| } | |||
| .content-margin { | |||
| margin: 10px 5px; | |||
| } | |||
| .tab_2_content { | |||
| min-height: 460px; | |||
| margin-left: 10px; | |||
| } | |||
| .ac-grid { | |||
| display: block; | |||
| *zoom: 1; | |||
| } | |||
| .ac-grid-col { | |||
| float: left; | |||
| width: 100%; | |||
| } | |||
| .ac-grid-col2 .ac-grid-col { | |||
| width: 50%; | |||
| } | |||
| .ti-form { | |||
| text-align: left; | |||
| max-width: 100%; | |||
| vertical-align: middle; | |||
| } | |||
| .ti-form>tbody { | |||
| font-size: 12px; | |||
| } | |||
| .ti-form>tbody, | |||
| .ti-form>tbody>tr { | |||
| vertical-align: inherit; | |||
| } | |||
| .info_text { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| font-size: 12px; | |||
| } | |||
| .ti-text-form-label { | |||
| padding-bottom: 20px; | |||
| padding-right: 20px; | |||
| color: #8a8e99; | |||
| font-size: 12px; | |||
| white-space: nowrap !important; | |||
| width: 80px; | |||
| line-height: 30px; | |||
| } | |||
| .ti-text-form-content { | |||
| line-height: 30px; | |||
| padding-bottom: 20px; | |||
| } | |||
| .ti-form>tbody>tr>td { | |||
| vertical-align: top; | |||
| white-space: normal; | |||
| } | |||
| td, | |||
| th { | |||
| padding: 0; | |||
| } | |||
| .ac-grid-col .text-span { | |||
| width: 450px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| } | |||
| .text-span-new { | |||
| width: 800px; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| height: 20%; | |||
| word-break: break-all; | |||
| } | |||
| .redo-color { | |||
| color: #3291F8; | |||
| } | |||
| .ti-action-menu-item:not(:last-child) { | |||
| margin-right: 10px; | |||
| padding-right: 11px; | |||
| text-decoration: none !important; | |||
| color: #526ecc; | |||
| cursor: pointer; | |||
| display: inline-block; | |||
| -moz-user-select: none; | |||
| -webkit-user-select: none; | |||
| -ms-user-select: none; | |||
| -khtml-user-select: none; | |||
| user-select: none; | |||
| position: relative; | |||
| } | |||
| .ti-action-menu-item:not(:last-child):after { | |||
| content: ""; | |||
| display: inline-block; | |||
| position: absolute; | |||
| height: 12px; | |||
| right: 0; | |||
| top: 50%; | |||
| -webkit-transform: translateY(-6px); | |||
| -ms-transform: translateY(-6px); | |||
| -o-transform: translateY(-6px); | |||
| transform: translateY(-6px); | |||
| border-right: 1px solid #dfe1e6; | |||
| } | |||
| .text-width80 { | |||
| width: 100px; | |||
| line-height: 30px; | |||
| } | |||
| .border-according { | |||
| border: 1px solid #dfe1e6; | |||
| } | |||
| .disabled { | |||
| cursor: default; | |||
| pointer-events: none; | |||
| color: rgba(0,0,0,.6) !important; | |||
| color: rgba(0, 0, 0, .6) !important; | |||
| opacity: .45 !important; | |||
| } | |||
| .pad20{ | |||
| border:0px !important; | |||
| } | |||
| .model_file_bread{ | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem ; | |||
| } | |||
| } | |||
| .pad20 { | |||
| border: 0px !important; | |||
| } | |||
| .model_file_bread { | |||
| margin-bottom: -0.5rem !important; | |||
| padding-left: 1rem; | |||
| padding-top: 0.5rem; | |||
| } | |||
| </style> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| @@ -185,7 +219,7 @@ td, th { | |||
| </div> | |||
| </div> | |||
| <div class="repository"> | |||
| {{template "repo/header" .}} | |||
| {{template "repo/header" .}} | |||
| <div class="ui container"> | |||
| <h4 class="ui header" id="vertical-segment"> | |||
| <div class="ui breadcrumb"> | |||
| @@ -194,36 +228,42 @@ td, th { | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| <a class="section backTodeBug" href="{{.RepoLink}}/debugjob?debugListType=all"> | |||
| {{$.i18n.Tr "repo.modelarts.notebook"}} | |||
| {{$.i18n.Tr "repo.modelarts.notebook"}} | |||
| </a> | |||
| <div class="divider"> / </div> | |||
| {{with .task}} | |||
| {{with .task}} | |||
| <div class="active section">{{.DisplayJobName}}</div> | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </h4> | |||
| {{with .task}} | |||
| <div class="ui accordion border-according" id="accordion" data-repopath="" data-jobid="" data-version=""> | |||
| <div class="ui accordion border-according" id="accordion" data-repopath="{{$.RepoRelPath}}/modelarts/notebook" | |||
| data-jobid="{{.ID}}" data-version=""> | |||
| <div class="active title padding0"> | |||
| <div class="according-panel-heading"> | |||
| <div class="accordion-panel-title"> | |||
| <!-- <i class="dropdown icon"></i> --> | |||
| <!-- <i class="dropdown icon"></i> --> | |||
| <span class="accordion-panel-title-content"> | |||
| <span> | |||
| <div class="ac-display-inblock title_text acc-margin-bottom"> | |||
| <span class="cti-mgRight-sm"> | |||
| {{if not (eq .StartTime 0)}} | |||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||
| {{else}} | |||
| <td>{{TimeSinceUnix1 .CreatedUnix}}<td> | |||
| {{end}} | |||
| </span> | |||
| {{if not (eq .StartTime 0)}} | |||
| <td>{{TimeSinceUnix1 .StartTime}}</td> | |||
| {{else}} | |||
| <td>{{TimeSinceUnix1 .CreatedUnix}} | |||
| <td> | |||
| {{end}} | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.status"}}: | |||
| <span id="{{.VersionName}}-status-span"><i id="icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <span id="{{.VersionName}}-status-span"><i id="icon" | |||
| style="vertical-align: middle;" class="{{.Status}}"></i><span id="text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| <span class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
| <span | |||
| class="cti-mgRight-sm">{{$.i18n.Tr "repo.modelarts.train_job.dura_time"}}:</span> | |||
| <span class="cti-mgRight-sm uc-accordionTitle-black" | |||
| id="{{.VersionName}}-duration-span">{{$.duration}}</span> | |||
| </div> | |||
| </span> | |||
| @@ -265,36 +305,38 @@ td, th { | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain_creator"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.User.Name}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-mirror"> | |||
| {{.User.Name}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.computing_resources"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-computeresource"> | |||
| {{.ComputeResource}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.computing_resources"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-computeresource"> | |||
| {{.ComputeResource}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.createtime"}} | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.createtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-createtime"> | |||
| {{TimeSinceUnix1 .CreatedUnix}} | |||
| </div> | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-createtime"> | |||
| {{TimeSinceUnix1 .CreatedUnix}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| @@ -303,40 +345,41 @@ td, th { | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-duration"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-duration"> | |||
| {{$.duration}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.datasetdownload"}} | |||
| </td> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.datasetdownload"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span-new" id="model_description"> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span-new" id="model_description"> | |||
| {{$.datasetDownloadLink}} | |||
| </div> | |||
| </td> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.description"}} | |||
| </td> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "cloudbrain.description"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span-new" id="model_description"> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span-new" id="model_description"> | |||
| {{.Description}} | |||
| </div> | |||
| </td> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| <div class="ac-grid-col"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <table class="ti-form"> | |||
| <tbody class="ti-text-form"> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| @@ -350,33 +393,34 @@ td, th { | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{.DatasetName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.dataset"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-BenchmarkTypeName"> | |||
| {{.DatasetName}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_spec}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.modelarts.train_job.standard"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| {{$.resource_spec}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.starttime"}} | |||
| @@ -384,44 +428,46 @@ td, th { | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-startTime"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-startTime"> | |||
| {{if not (eq .StartTime 0)}} | |||
| {{TimeSinceUnix1 .StartTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| {{TimeSinceUnix1 .StartTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| <tr class="ti-no-ng-animate"> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" id="{{.VersionName}}-EndTime"> | |||
| {{if not (eq .EndTime 0)}} | |||
| {{TimeSinceUnix1 .EndTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| <td class="ti-no-ng-animate ti-text-form-label text-width80"> | |||
| {{$.i18n.Tr "repo.cloudbrain.time.endtime"}} | |||
| </td> | |||
| <td class="ti-text-form-content"> | |||
| <div class="text-span text-span-w" | |||
| id="{{.VersionName}}-EndTime"> | |||
| {{if not (eq .EndTime 0)}} | |||
| {{TimeSinceUnix1 .EndTime}} | |||
| {{else}} | |||
| -- | |||
| {{end}} | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -457,24 +503,10 @@ td, th { | |||
| <script> | |||
| $('.menu .item').tab() | |||
| $(document).ready(function(){ | |||
| $('.ui.accordion').accordion({selector:{trigger:'.icon'}}); | |||
| $(document).ready(function () { | |||
| $('.ui.accordion').accordion({ selector: { trigger: '.icon' } }); | |||
| }); | |||
| $(document).ready(function(){ | |||
| $(document).ready(function () { | |||
| $('.secondary.menu .item').tab(); | |||
| }); | |||
| let userName | |||
| let repoPath | |||
| let jobName | |||
| $(document).ready(function(){ | |||
| let url = window.location.href; | |||
| let urlArr = url.split('/') | |||
| userName = urlArr.slice(-5)[0] | |||
| repoPath = urlArr.slice(-4)[0] | |||
| jobName = urlArr.slice(-1)[0] | |||
| }) | |||
| </script> | |||
| </script> | |||
| @@ -239,7 +239,7 @@ const params = new URLSearchParams(location.search) | |||
| if(!location.search){ | |||
| $('.default.text').text(all) | |||
| }else{ | |||
| if(params.has('listType') && params.get('listType')=='all'){ | |||
| if(!params.has('listType') || params.get('listType')=='all'){ | |||
| $('.default.text').text(all) | |||
| } | |||
| else{ | |||
| @@ -1,109 +1,174 @@ | |||
| <table id="repo-files-table" class="ui single line table"> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| <div class="rect3"></div> | |||
| <div class="rect4"></div> | |||
| <div class="rect5"></div> | |||
| </div> | |||
| </div> | |||
| <table id="repo-files-table" class="ui single line table can-context-menu" data-can-editfile="{{.CanEditFile}}"> | |||
| {{.CsrfTokenHtml}} | |||
| <thead> | |||
| <tr class="commit-list"> | |||
| <th colspan="2"> | |||
| {{if .LatestCommitUser}} | |||
| <img class="ui avatar image img-12" src="{{.LatestCommitUser.RelAvatarLink}}" /> | |||
| {{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}} | |||
| <img class="ui avatar image img-12" src="{{.LatestCommitUser.RelAvatarLink}}" /> | |||
| {{if .LatestCommitUser.FullName}} | |||
| <a href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{.LatestCommitUser.FullName}}</strong></a> | |||
| {{else}} | |||
| {{if .LatestCommit.Author}} | |||
| <img class="ui avatar image img-12" src="{{AvatarLink .LatestCommit.Author.Email}}" /> | |||
| <strong>{{.LatestCommit.Author.Name}}</strong> | |||
| {{end}} | |||
| <a | |||
| href="{{AppSubUrl}}/{{.LatestCommitUser.Name}}"><strong>{{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}}</strong></a> | |||
| {{end}} | |||
| <a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}"> | |||
| {{else}} | |||
| {{if .LatestCommit.Author}} | |||
| <img class="ui avatar image img-12" src="{{AvatarLink .LatestCommit.Author.Email}}" /> | |||
| <strong>{{.LatestCommit.Author.Name}}</strong> | |||
| {{end}} | |||
| {{end}} | |||
| <a rel="nofollow" | |||
| class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" | |||
| href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}"> | |||
| <span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span> | |||
| {{if .LatestCommit.Signature}} | |||
| <div class="ui detail icon button"> | |||
| {{if .LatestCommitVerification.Verified}} | |||
| <div title="{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user"}}: {{else}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}: {{end}}{{.LatestCommitVerification.Reason}}"> | |||
| {{if ne .LatestCommitVerification.SigningUser.ID 0}} | |||
| <i class="lock icon"></i> | |||
| <img class="ui signature avatar image" src="{{.LatestCommitVerification.SigningUser.RelAvatarLink}}" /> | |||
| {{else}} | |||
| <i title="{{.LatestCommitVerification.Reason}}" class="icons"> | |||
| <i class="lock icon"></i> | |||
| <i class="tiny inverted cog icon centerlock"></i> | |||
| </i> | |||
| <img class="ui signature avatar image" src="{{AvatarLink .LatestCommitVerification.SigningEmail}}" /> | |||
| {{end}} | |||
| </div> | |||
| <div class="ui detail icon button"> | |||
| {{if .LatestCommitVerification.Verified}} | |||
| <div | |||
| title="{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user"}}: {{else}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}: {{end}}{{.LatestCommitVerification.Reason}}"> | |||
| {{if ne .LatestCommitVerification.SigningUser.ID 0}} | |||
| <i class="lock icon"></i> | |||
| <img class="ui signature avatar image" | |||
| src="{{.LatestCommitVerification.SigningUser.RelAvatarLink}}" /> | |||
| {{else}} | |||
| <i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i> | |||
| <i title="{{.LatestCommitVerification.Reason}}" class="icons"> | |||
| <i class="lock icon"></i> | |||
| <i class="tiny inverted cog icon centerlock"></i> | |||
| </i> | |||
| <img class="ui signature avatar image" | |||
| src="{{AvatarLink .LatestCommitVerification.SigningEmail}}" /> | |||
| {{end}} | |||
| </div> | |||
| {{else}} | |||
| <i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i> | |||
| {{end}} | |||
| </div> | |||
| {{end}} | |||
| </a> | |||
| {{template "repo/commit_status" .LatestCommitStatus}} | |||
| {{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }} | |||
| <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 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 class="text grey right age">{{if .LatestCommit.Author}}{{TimeSince .LatestCommit.Author.When $.Lang}}{{end}}</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-mail-reply" 16}}<a href="{{EscapePound .BranchLink}}{{.ParentPath}}">..</a></td> | |||
| </tr> | |||
| <tr class="has-parent"> | |||
| <td colspan="3">{{svg "octicon-mail-reply" 16}}<a href="{{EscapePound .BranchLink}}{{.ParentPath}}">..</a> | |||
| </td> | |||
| </tr> | |||
| {{end}} | |||
| {{range $item := .Files}} | |||
| {{$entry := index $item 0}} | |||
| {{$commit := index $item 1}} | |||
| <tr> | |||
| {{if $entry.IsSubModule}} | |||
| <td> | |||
| <span class="truncate"> | |||
| {{svg "octicon-inbox" 16}} | |||
| {{$refURL := $commit.RefURL AppUrl $.Repository.FullName}} | |||
| {{if $refURL}} | |||
| <a href="{{$refURL}}">{{$entry.Name}}</a> @ <a href="{{$refURL}}/commit/{{$commit.RefID}}">{{ShortSha $commit.RefID}}</a> | |||
| {{else}} | |||
| {{$entry.Name}} @ {{ShortSha $commit.RefID}} | |||
| {{end}} | |||
| </span> | |||
| </td> | |||
| {{else}} | |||
| <td class="name four wide"> | |||
| <span class="truncate"> | |||
| {{if $entry.IsDir}} | |||
| {{$subJumpablePathName := $entry.GetSubJumpablePathName}} | |||
| {{$subJumpablePath := SubJumpablePath $subJumpablePathName}} | |||
| {{svg "octicon-file-directory" 16}} | |||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $subJumpablePathName}}" title="{{$subJumpablePathName}}"> | |||
| {{if eq (len $subJumpablePath) 2}} | |||
| <span class="jumpable-path">{{index $subJumpablePath 0}}</span>{{index $subJumpablePath 1}} | |||
| {{else}} | |||
| {{index $subJumpablePath 0}} | |||
| {{end}} | |||
| </a> | |||
| {{else}} | |||
| {{svg (printf "octicon-%s" (EntryIcon $entry)) 16}} | |||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $entry.Name}}" title="{{$entry.Name}}">{{$entry.Name}}</a> | |||
| {{end}} | |||
| </span> | |||
| </td> | |||
| {{end}} | |||
| <td class="message nine wide"> | |||
| <span class="truncate"> | |||
| <a href="{{$.RepoLink}}/commit/{{$commit.ID}}" title="{{$commit.Summary}}">{{$commit.Summary | RenderEmoji}}</a> | |||
| </span> | |||
| </td> | |||
| <td class="text right age three wide">{{TimeSince $commit.Committer.When $.Lang}}</td> | |||
| </tr> | |||
| {{$entry := index $item 0}} | |||
| {{$commit := index $item 1}} | |||
| <tr> | |||
| {{if $entry.IsSubModule}} | |||
| <td> | |||
| <span class="truncate"> | |||
| {{svg "octicon-inbox" 16}} | |||
| {{$refURL := $commit.RefURL AppUrl $.Repository.FullName}} | |||
| {{if $refURL}} | |||
| <a href="{{$refURL}}">{{$entry.Name}}</a> @ <a | |||
| href="{{$refURL}}/commit/{{$commit.RefID}}">{{ShortSha $commit.RefID}}</a> | |||
| {{else}} | |||
| {{$entry.Name}} @ {{ShortSha $commit.RefID}} | |||
| {{end}} | |||
| </span> | |||
| </td> | |||
| {{else}} | |||
| <td class="name four wide modified-contextmenu"> | |||
| <span class="truncate"> | |||
| {{if $entry.IsDir}} | |||
| {{$subJumpablePathName := $entry.GetSubJumpablePathName}} | |||
| {{$subJumpablePath := SubJumpablePath $subJumpablePathName}} | |||
| {{svg "octicon-file-directory" 16}} | |||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $subJumpablePathName}}" | |||
| title="{{$subJumpablePathName}}"> | |||
| {{if eq (len $subJumpablePath) 2}} | |||
| <span class="jumpable-path">{{index $subJumpablePath 0}}</span>{{index $subJumpablePath 1}} | |||
| {{else}} | |||
| {{index $subJumpablePath 0}} | |||
| {{end}} | |||
| </a> | |||
| {{else}} | |||
| {{svg (printf "octicon-%s" (EntryIcon $entry)) 16}} | |||
| <a href="{{EscapePound $.TreeLink}}/{{EscapePound $entry.Name}}" | |||
| title="{{$entry.Name}}">{{$entry.Name}}</a> | |||
| {{end}} | |||
| </span> | |||
| </td> | |||
| {{end}} | |||
| <td class="message nine wide"> | |||
| <span class="truncate"> | |||
| <a href="{{$.RepoLink}}/commit/{{$commit.ID}}" | |||
| title="{{$commit.Summary}}">{{$commit.Summary | RenderEmoji}}</a> | |||
| </span> | |||
| </td> | |||
| <td class="text right age three wide">{{TimeSince $commit.Committer.When $.Lang}}</td> | |||
| </tr> | |||
| <tr style="display: none !important;" class="context-menu-one"> | |||
| <td colspan="12"> | |||
| <div class="ui column form" method="POST"> | |||
| <div class="two fields" style="margin: 0;"> | |||
| <div class="five wide field"> | |||
| <input class="ui input" name="new_filename" type="text" value="" | |||
| onkeyup="this.value=this.value.replace(/[, ]/g,'')"> | |||
| </div> | |||
| <div class="five wide field"> | |||
| <button class="ui blue button popup-save" type="button" | |||
| data-postBasePath="{{$.RepoLink}}/_rename/{{EscapePound $.BranchName}}{{if $.TreePath}}/{{EscapePound $.TreePath}}{{end}}/{{$entry.Name}}" | |||
| data-commit="{{$.LatestCommit.ID}}" | |||
| data-treepath="{{if $.TreePath}}{{EscapePound $.TreePath}}/{{end}}">保存</button> | |||
| <button class="ui basic button popup-close" type="button">取消</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </td> | |||
| </tr> | |||
| {{end}} | |||
| </tbody> | |||
| </table> | |||
| {{if .ReadmeExist}} | |||
| {{template "repo/view_file" .}} | |||
| {{template "repo/view_file" .}} | |||
| {{end}} | |||
| <!-- 确认模态框 --> | |||
| <div id="deletemodel"> | |||
| <div class="ui basic modal context-menu-delete"> | |||
| <div class="ui icon header"> | |||
| <i class="trash icon"></i> {{.i18n.Tr "cloudbrain.delete_task"}} | |||
| </div> | |||
| <div class="content"> | |||
| <p>{{.i18n.Tr "cloudbrain.task_delete_confirm"}}</p> | |||
| </div> | |||
| <div class="actions"> | |||
| <div class="ui red basic inverted cancel button"> | |||
| <i class="remove icon"></i> {{.i18n.Tr "cloudbrain.operate_cancel"}} | |||
| </div> | |||
| <div class="ui green basic inverted ok button"> | |||
| <i class="checkmark icon"></i> {{.i18n.Tr "cloudbrain.operate_confirm"}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -1,6 +1,6 @@ | |||
| {{template "base/head" .}} | |||
| <!-- 弹窗 --> | |||
| <div id="mask"> | |||
| <!-- 弹窗 --> | |||
| <div id="mask"> | |||
| <div id="loadingPage"> | |||
| <div class="rect1"></div> | |||
| <div class="rect2"></div> | |||
| @@ -12,16 +12,22 @@ | |||
| <!-- 提示框 --> | |||
| <div class="alert"></div> | |||
| <div class="explore users"> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" data-debug-again="{{$.i18n.Tr "repo.debug_again"}}"></div> | |||
| <div class="cloudbrain_debug" style="display: none;" data-debug="{{$.i18n.Tr "repo.debug"}}" | |||
| data-debug-again="{{$.i18n.Tr "repo.debug_again"}}" data-debug-task="{{$.i18n.Tr "cloudbrain.DEBUG"}}" | |||
| data-train-task="{{$.i18n.Tr "cloudbrain.TRAIN"}}" data-inference-task="{{$.i18n.Tr "cloudbrain.INFERENCE"}}" | |||
| data-benchmark-task="{{$.i18n.Tr "cloudbrain.BENCHMARK"}}" | |||
| data-all-task="{{.i18n.Tr "admin.cloudbrain.all_task_types"}}" | |||
| data-all-compute="{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}" | |||
| data-all-status="{{.i18n.Tr "admin.cloudbrain.all_status"}}"></div> | |||
| {{template "admin/cloudbrain/search_dashboard" .}} | |||
| <div class="ui container" style="width: 80%;"> | |||
| {{template "base/alert" .}} | |||
| <div class="ui grid" > | |||
| <div class="row" > | |||
| <div class="ui grid"> | |||
| <div class="row"> | |||
| <div class="ui sixteen wide column"> | |||
| <!-- 任务展示 --> | |||
| <div class="dataset list"> | |||
| <!-- 表头 --> | |||
| <!-- 表头 --> | |||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | |||
| <div class="row"> | |||
| <div class="three wide column nowrap" style="width:15%"> | |||
| @@ -34,19 +40,19 @@ | |||
| <span style="margin:0 6px">{{$.i18n.Tr "repo.cloudbrain_task_type"}}</span> | |||
| </div> | |||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| <span>{{$.i18n.Tr "repo.modelarts.createtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_status_runtime"}}</span> | |||
| </div> | |||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| <span>{{$.i18n.Tr "repo.modelarts.computing_resources"}}</span> | |||
| </div> | |||
| <div class="two wide column text center nowrap" style="width: 14.5%!important;"> | |||
| <span>{{$.i18n.Tr "repository"}}</span> | |||
| </div> | |||
| <div class="three wide column text center nowrap" style="width: 21.5%!important;"> | |||
| <span>{{$.i18n.Tr "repo.cloudbrain_operate"}}</span> | |||
| </div> | |||
| @@ -65,66 +71,100 @@ | |||
| {{end}} | |||
| <!-- {{$JobID}} --> | |||
| <div class="three wide column nowrap" style="width:15%"> | |||
| {{if or (eq .JobType "DEBUG") (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain/{{$JobID}}{{else}}/modelarts/notebook/{{$JobID}}{{end}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}} | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .ComputeResource "NPU"}}modelarts{{else}}cloudbrain{{end}}/train-job/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .ComputeResource "NPU"}}modelarts{{else}}cloudbrain{{end}}/train-job/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <a class="title" | |||
| href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}/cloudbrain/benchmark/{{$JobID}}" | |||
| title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 11% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <div class="two wide column text center nowrap" | |||
| style="padding-left: 2.2rem !important; width: 11% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "DEBUG"}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}{{else if eq .JobType "INFERENCE"}}/modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{else if eq .JobType "BENCHMARK"}}/cloudbrain{{end}}' | |||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <!-- 任务类型 --> | |||
| {{$JobType := $.i18n.Tr (printf "cloudbrain.%s" .JobType)}} | |||
| <div class="one wide column text center nowrap" style="width:10%"> | |||
| <span style="font-size: 12px;" title="{{$JobType}}">{{$JobType}}</span> | |||
| <span style="font-size: 12px;" title="{{.JobType}}">{{$JobType}}</span> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| <span style="font-size: 12px;" | |||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| <span style="font-size: 12px;" | |||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| <span | |||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 项目 --> | |||
| <div class="two wide column text center nowrap" style="width: 14.5%!important;"> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||
| <a href="{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}" | |||
| title="{{.Repo.OwnerName}}/{{.Repo.Alias}}">{{.Repo.OwnerName}}/{{.Repo.Alias}}</a> | |||
| </div> | |||
| <div class="three wide column text center nowrap" style="width: 21.5%!important;"> | |||
| {{if eq .JobType "DEBUG" "SNN4IMAGENET" "BRAINSCORE"}} | |||
| {{if eq .JobType "DEBUG"}} | |||
| <div class="ui compact buttons"> | |||
| <form id="debugAgainForm-{{$JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" | |||
| class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}}disabled {{else}}blue {{end}}button' | |||
| data-jobid="{{$JobID}}" | |||
| data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' data-jobid="{{$JobID}}" data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| <a id="ai-debug-{{$JobID}}" | |||
| class='ui basic ai_debug {{if eq .Status "CREATING" "STOPPING" "WAITING" "STARTING"}} disabled {{else}}blue {{end}}button' | |||
| data-jobid="{{$JobID}}" | |||
| data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else}}/modelarts/notebook{{end}}/{{$JobID}}/'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -134,22 +174,42 @@ | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| {{if eq .JobType "DEBUG" "BENCHMARK" "SNN4IMAGENET" "BRAINSCORE"}} | |||
| <form id="stopForm-{{$JobID}}" style="margin-left:-1px;"> | |||
| <form id="stopForm-{{$JobID}}" style="margin-left:-1px;"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop' data-jobid="{{$JobID}}"> | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
| class='ui basic ai_stop {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "SUCCEEDED" "STOPPED" "STOPPING" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' | |||
| data-repopath='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .ComputeResource "CPU/GPU"}}/cloudbrain{{else if eq .JobType "BENCHMARK" }}/cloudbrain/benchmark{{else if eq .ComputeResource "NPU" }}/modelarts/notebook{{end}}/{{$JobID}}/stop' | |||
| data-jobid="{{$JobID}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </form> | |||
| {{else}} | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class='ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "STOPPED" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}modelarts/train-job{{else}}cloudbrain/train-job{{end}}{{end}}' data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
| class='ui basic ai_stop_version {{if eq .Status "KILLED" "FAILED" "START_FAILED" "KILLING" "COMPLETED" "STOPPED" "SUCCEEDED" "CREATE_FAILED"}}disabled {{else}} blue {{end}}button' | |||
| data-repopath='{{.Repo.OwnerName}}/{{.Repo.Name}}/{{if eq .JobType "INFERENCE"}}modelarts/inference-job{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}modelarts/train-job{{else}}cloudbrain/train-job{{end}}{{end}}' | |||
| data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| {{if eq .JobType "BENCHMARK"}} | |||
| <div class="ui compact buttons"> | |||
| <a class="ui basic button {{if $.IsSigned}} blue{{else}} disabled{{end}}" | |||
| href="{{$.RepoLink}}/cloudbrain/{{.Cloudbrain.ID}}/rate" target="_blank"> | |||
| {{$.i18n.Tr "repo.score"}} | |||
| </a> | |||
| </div> | |||
| {{end}} | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true' method="post"> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" | |||
| action='{{AppSubUrl}}/{{.Repo.OwnerName}}/{{.Repo.Name}}{{if eq .JobType "BENCHMARK"}}/cloudbrain/benchmark{{else if or (eq .JobType "SNN4IMAGENET") (eq .JobType "BRAINSCORE")}}/cloudbrain{{else if eq .JobType "DEBUG"}}{{if eq .ComputeResource "NPU"}}/modelarts/notebook{{else}}/cloudbrain{{end}}{{else if eq .JobType "TRAIN"}}{{if eq .ComputeResource "NPU"}}/modelarts/train-job{{else}}/cloudbrain/train-job{{end}}{{end}}/{{$JobID}}/del?ishomepage=true' | |||
| method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?ishomepage=true" data-version="" class="ui basic ai_delete blue button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | |||
| data-repopath="{{.Repo.OwnerName}}/{{.Repo.Name}}/modelarts/inference-job/{{$JobID}}/del_version?ishomepage=true" | |||
| data-version="" class="ui basic ai_delete blue button" | |||
| style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| @@ -169,48 +229,59 @@ | |||
| <div class="three wide column nowrap" style="width:15%"> | |||
| {{if eq .JobType "DEBUG"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "INFERENCE"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "TRAIN"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{else if eq .JobType "BENCHMARK"}} | |||
| <a class="title" href="" title="{{.DisplayJobName}}" style="font-size: 14px;"> | |||
| <span class="fitted" style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| <span class="fitted" | |||
| style="width: 90%;vertical-align: middle;">{{.DisplayJobName}}</span> | |||
| </a> | |||
| {{end}} | |||
| </div> | |||
| <!-- 任务状态 --> | |||
| <div class="two wide column text center nowrap" style="padding-left: 2.2rem !important; width: 11% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" class="{{.Status}}"></i><span id="{{$JobID}}-text" style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| <div class="two wide column text center nowrap" | |||
| style="padding-left: 2.2rem !important; width: 11% !important;"> | |||
| <span class="job-status" id="{{$JobID}}" data-jobid="{{$JobID}}" | |||
| data-version="{{.VersionName}}"> | |||
| <span><i id="{{$JobID}}-icon" style="vertical-align: middle;" | |||
| class="{{.Status}}"></i><span id="{{$JobID}}-text" | |||
| style="margin-left: 0.4em;font-size: 12px;">{{.Status}}</span></span> | |||
| </span> | |||
| </div> | |||
| <!-- 任务类型 --> | |||
| {{$JobType := $.i18n.Tr (printf "cloudbrain.%s" .JobType)}} | |||
| <div class="one wide column text center nowrap" style="width:10%"> | |||
| <span style="font-size: 12px;" title="{{$JobType}}">{{$JobType}}</span> | |||
| <span style="font-size: 12px;" title="{{.JobType}}">{{$JobType}}</span> | |||
| </div> | |||
| <!-- 任务创建时间 --> | |||
| <div class="two wide column text center nowrap" style="width: 11% !important;"> | |||
| <span style="font-size: 12px;" class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| <span style="font-size: 12px;" | |||
| class="">{{TimeSinceUnix1 .Cloudbrain.CreatedUnix}}</span> | |||
| </div> | |||
| <!-- 任务运行时间 --> | |||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||
| <span style="font-size: 12px;" id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| <span style="font-size: 12px;" | |||
| id="duration-{{$JobID}}">{{if .TrainJobDuration}}{{.TrainJobDuration}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 计算资源 --> | |||
| <div class="one wide column text center nowrap" style="width:8.5% !important;"> | |||
| <span style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| <span | |||
| style="font-size: 12px;">{{if .ComputeResource}}{{.ComputeResource}}{{else}}--{{end}}</span> | |||
| </div> | |||
| <!-- 创建者 --> | |||
| <!-- 项目 --> | |||
| <div class="two wide column text center nowrap" style="width: 14.5%!important;"> | |||
| <a href="" title="">--</a> | |||
| @@ -221,11 +292,12 @@ | |||
| <form id="debugAgainForm-{{$JobID}}"> | |||
| {{$.CsrfTokenHtml}} | |||
| {{if eq .Status "RUNNING" "WAITING" "CREATING" "STARTING"}} | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||
| <a style="margin: 0 1rem;" id="ai-debug-{{$JobID}}" | |||
| class='ui basic disabled button'> | |||
| {{$.i18n.Tr "repo.debug"}} | |||
| </a> | |||
| {{else}} | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic disabled button' > | |||
| <a id="ai-debug-{{$JobID}}" class='ui basic disabled button'> | |||
| {{$.i18n.Tr "repo.debug_again"}} | |||
| </a> | |||
| {{end}} | |||
| @@ -234,14 +306,17 @@ | |||
| {{end}} | |||
| <!-- 停止任务 --> | |||
| <div class="ui compact buttons"> | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" class="ui basic disabled button" data-jobid="{{$JobID}}" data-version="{{.VersionName}}" > | |||
| <a style="padding: 0.5rem 1rem;" id="ai-stop-{{$JobID}}" | |||
| class="ui basic disabled button" data-jobid="{{$JobID}}" | |||
| data-version="{{.VersionName}}"> | |||
| {{$.i18n.Tr "repo.stop"}} | |||
| </a> | |||
| </div> | |||
| <!-- 删除任务 --> | |||
| <form class="ui compact buttons" id="delForm-{{$JobID}}" action='' method="post"> | |||
| {{$.CsrfTokenHtml}} | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||
| <a style="padding: 0.5rem 1rem;margin-left:0.2rem" id="ai-delete-{{$JobID}}" | |||
| class="ui basic disabled button" style="border-radius: .28571429rem;"> | |||
| {{$.i18n.Tr "repo.delete"}} | |||
| </a> | |||
| </form> | |||
| @@ -253,14 +328,9 @@ | |||
| {{end}} | |||
| <div id="app" style="margin-top: 2rem;"> | |||
| <div class="center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-sizes="[10]" | |||
| :page-size="10" | |||
| layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| <el-pagination background @current-change="handleCurrentChange" :current-page="page" | |||
| :page-sizes="[10]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" | |||
| :total="{{.Page.Paginater.Total}}"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| @@ -291,38 +361,4 @@ | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{template "base/footer" .}} | |||
| <script> | |||
| function getParams(){ | |||
| const params = new URLSearchParams(window.location.search) | |||
| params.get('jobType') | |||
| let jobType | |||
| if(!params.get('jobType')){ | |||
| jobType = '{{.i18n.Tr "admin.cloudbrain.all_task_types"}}' | |||
| }else{ | |||
| if(params.get('jobType') === 'DEBUG'){ | |||
| jobType = '{{$.i18n.Tr (printf "cloudbrain.DEBUG")}}' | |||
| }else if(params.get('jobType') === 'TRAIN'){ | |||
| jobType = '{{$.i18n.Tr (printf "cloudbrain.TRAIN")}}' | |||
| } | |||
| else if(params.get('jobType') === 'INFERENCE'){ | |||
| jobType = '{{$.i18n.Tr (printf "cloudbrain.INFERENCE")}}' | |||
| } | |||
| else if(params.get('jobType') === 'SNN4IMAGENET'){ | |||
| jobType = '{{$.i18n.Tr (printf "cloudbrain.SNN4IMAGENET")}}' | |||
| }else if(params.get('jobType') === 'BENCHMARK'){ | |||
| jobType = '{{$.i18n.Tr (printf "cloudbrain.BENCHMARK")}}' | |||
| } | |||
| else{ | |||
| jobType = '{{$.i18n.Tr (printf "cloudbrain.BRAINSCORE")}}' | |||
| } | |||
| } | |||
| let listType = !params.get('listType')? '{{.i18n.Tr "admin.cloudbrain.all_computing_resources"}}' : params.get('listType') | |||
| let jobStatus = !params.get('jobStatus')? '{{.i18n.Tr "admin.cloudbrain.all_status"}}' : params.get('jobStatus').toUpperCase() | |||
| const dropdownValueArray = [jobType,listType,jobStatus] | |||
| $('#adminCloud .default.text ').each(function(index,e){ | |||
| $(e).text(dropdownValueArray[index]) | |||
| }) | |||
| } | |||
| getParams() | |||
| </script> | |||
| {{template "base/footer" .}} | |||
| @@ -1,108 +1,61 @@ | |||
| <template> | |||
| <div style="height:100%"> | |||
| <el-tabs tab-position="left" v-model="activeName" style="height:100%" @tab-click="handleClick" > | |||
| <el-tab-pane label="概览" name="first" > | |||
| <span slot="label"> | |||
| <el-image style="width: 13px; height: 13px" src="/img/overview_rgb.svg"> | |||
| </el-image> | |||
| 概览 | |||
| </span> | |||
| <div >暂无内容.......</div> | |||
| <el-row style="height:100%;width: 100%; flex:1" > | |||
| <el-col :span="3" style="height:100%;padding-right:15px;"> | |||
| <el-menu | |||
| :default-active="this.$router.path" | |||
| class="el-menu-vertical-demo" | |||
| :router="true" style="height:100%; background-color: #F5F5F6;" > | |||
| <el-menu-item index="/Overview" > | |||
| <i class="ri-home-4-line"></i> | |||
| <span slot="title">概览</span> | |||
| </el-menu-item> | |||
| <el-submenu index="/"> | |||
| <template slot="title"> | |||
| <i class="ri-numbers-line"></i> | |||
| <span>项目分析</span> | |||
| </template> | |||
| <el-menu-item index="/ProTrend">增长趋势分析</el-menu-item> | |||
| <el-menu-item index="/ProAnalysis">详细数据</el-menu-item> | |||
| </el-submenu> | |||
| <el-submenu index="2"> | |||
| <template slot="title"> | |||
| <i class="ri-contacts-line"></i> | |||
| <span>用户分析</span> | |||
| </template> | |||
| <el-menu-item index="/UserTrend">增长趋势分析</el-menu-item> | |||
| <el-menu-item index="/UserAnalysis">活动分析</el-menu-item> | |||
| </el-submenu> | |||
| <el-menu-item index="/BrainAnalysis"> | |||
| <i class="ri-server-fill"></i> | |||
| <span slot="title">云脑分析(建设中..)</span> | |||
| </el-menu-item> | |||
| </el-menu> | |||
| </el-col> | |||
| <router-view> </router-view> | |||
| </el-row> | |||
| </template> | |||
| </el-tab-pane> | |||
| <el-tab-pane label="项目分析" name="second" id="second" > | |||
| <ProAnalysis ref='ProAnalysis'id="pro" v-if="isRouterAlive"></ProAnalysis> | |||
| <span slot="label"> | |||
| <el-image style="width: 13px; height: 13px" src="/img/pro_rgb.svg"> | |||
| </el-image> | |||
| 项目分析 | |||
| </span> | |||
| </el-tab-pane> | |||
| <el-tab-pane name="third" id='third' > | |||
| <span slot='label'> | |||
| <el-image style="width: 13px; height: 13px" src="/img/user_rgb.svg"> | |||
| </el-image> | |||
| 用户分析 | |||
| </span> | |||
| <UserAnalysis ref='UserAnalysis' v-if="isRouterAlive1" id ="usr"></UserAnalysis> | |||
| </el-tab-pane> | |||
| <el-tab-pane name="four" id='four' > | |||
| <BrainAnalysis ref='BrainAnalysis'id="brain" v-if="isRouterAlive"></BrainAnalysis> | |||
| <span slot="label"> | |||
| <el-image style="width: 13px; height: 13px" src="/img/pro_rgb.svg"> | |||
| </el-image> | |||
| 云脑分析(建设中..) | |||
| </span> | |||
| </el-tab-pane> | |||
| </el-tabs> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import ProAnalysis from './ProAnalysis.vue' | |||
| import UserAnalysis from './UserAnalysis.vue' | |||
| import BrainAnalysis from './BrainAnalysis.vue' | |||
| export default { | |||
| components:{ | |||
| 'ProAnalysis':ProAnalysis, | |||
| 'UserAnalysis':UserAnalysis, | |||
| 'BrainAnalysis':BrainAnalysis, | |||
| }, | |||
| data() { | |||
| return { | |||
| activeName:"second", | |||
| loading:true, | |||
| loading1:true, | |||
| isRouterAlive: true, | |||
| isRouterAlive1: true, | |||
| isSecond:true, | |||
| isThird:false, | |||
| } | |||
| }, | |||
| methods:{ | |||
| handleClick(tab, event){ | |||
| if(tab.name=="second"){ | |||
| this.reload() | |||
| this.isSecond = true | |||
| this.isThird = false | |||
| this.$refs.ProAnalysis.getAllProList("all",7) | |||
| } | |||
| if(tab.name=="third"){ | |||
| this.reload1() | |||
| this.isSecond = false | |||
| this.isThird = true | |||
| this.$refs.UserAnalysis.getUpdateTime() | |||
| this.$refs.UserAnalysis.getUserList("all_usr",7) | |||
| } | |||
| }, | |||
| reload () { | |||
| this.isRouterAlive = false | |||
| this.$nextTick(() => (this.isRouterAlive = true)) | |||
| }, | |||
| reload1 () { | |||
| this.isRouterAlive1 = false | |||
| this.$nextTick(() => (this.isRouterAlive1 = true)) | |||
| } | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| <script> | |||
| export default{ | |||
| data(){ | |||
| return { | |||
| Path_router:'/' | |||
| } | |||
| }, | |||
| created(){ | |||
| var url_params = document.getElementById("url_params").value; | |||
| if (url_params!='' && url_params!=undefined && url_params!='/'){ | |||
| this.$router.path = '/'+url_params.split('/')[0] | |||
| }else{ | |||
| this.$router.path = '/ProAnalysis' | |||
| } | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| /deep/ .is-active{ | |||
| color: #238BFC ; | |||
| background-color: #FFFF ; | |||
| color: #238BFC ; | |||
| } | |||
| /deep/ .ui-container{ | |||
| background-color: #FFFF; | |||
| @@ -137,8 +90,26 @@ | |||
| /deep/ .el-tabs__item:hover .el-image{ | |||
| filter:none | |||
| } | |||
| /deep/ .el-image{ | |||
| filter:grayscale(100%) | |||
| .bk{ | |||
| background-color: #F5F5F6; | |||
| } | |||
| .el-menu-item.is-active { | |||
| color: #409eff; | |||
| background-color: #FFFFFF !important; | |||
| } | |||
| /deep/ .el-submenu.is-active .el-submenu__title { | |||
| color: #409eff | |||
| } | |||
| /deep/ .el-submenu.is-active .el-submenu__title i{ | |||
| color: #409eff | |||
| } | |||
| /deep/ .el-menu, .el-menu--horizontal>.el-menu-item:not(.is-disabled):focus, .el-menu--horizontal>.el-menu-item:not(.is-disabled):hover, .el-menu--horizontal>.el-submenu .el-submenu__title:hover { | |||
| background-color: #F5F5F6; | |||
| } | |||
| /deep/ .el-pagination { | |||
| padding-bottom: 30px; | |||
| } | |||
| </style> | |||
| </style> | |||
| @@ -0,0 +1,5 @@ | |||
| <template> | |||
| <div> | |||
| 暂无内容 | |||
| </div> | |||
| </template> | |||
| @@ -1,8 +1,8 @@ | |||
| <template> | |||
| <div style="width: 100%;"> | |||
| <div class="el-col el-col-21" style="padding-right:10px " > | |||
| <div id = "pro_main"> | |||
| <div style="margin-top: 10px;"> | |||
| <b class="pro_item">项目分析</b> <span class="update_time">数据更新时间:</span> <span style="font-size: 12px;">{{lastUpdatedTime}} / 从{{recordBeginTime}}开始统计</span> | |||
| <b class="pro_item">详细数据</b> <span class="update_time">数据更新时间:</span> <span style="font-size: 12px;">{{lastUpdatedTime}} / 从{{recordBeginTime}}开始统计</span> | |||
| </div> | |||
| <bar-label :width="'95%'" :height="'500px'"></bar-label> | |||
| @@ -29,11 +29,11 @@ | |||
| </span> | |||
| <span style="float:right; margin-right: 20px;"> | |||
| <div style="display:inline-block;margin-left: 20px; "> | |||
| <a class="el-icon-download" v-if="tableData!=''" :href= "'../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'" ></a> | |||
| <a class="el-icon-download" v-if="tableData!=''" :href= "'../../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'" ></a> | |||
| <i class="el-icon-download" v-else="tableData=''" href="#" style="color:rgba(187, 187, 187, 100);" @click='popMark()'></i> | |||
| <!-- <span ><a id = "download_file" :href= "'../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'" >下载报告</a> </span> --> | |||
| <span > | |||
| <a id = "download_file" v-if="tableData!=''" :href= "'../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'">下载报告</a> | |||
| <a id = "download_file" v-if="tableData!=''" :href= "'../../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'">下载报告</a> | |||
| <a id = "download_file" v-else="tableData=''" href= "#" style="color:rgba(187, 187, 187, 100);" @click='popMark()'>下载报告</a> | |||
| </span> | |||
| </div> | |||
| @@ -59,6 +59,7 @@ | |||
| > | |||
| </el-table-column> | |||
| <el-table-column | |||
| fixed | |||
| label="项目名称中文" | |||
| align="left" | |||
| prop="name" | |||
| @@ -404,8 +405,7 @@ | |||
| value_time: '', | |||
| search:'', | |||
| dynamic:7, | |||
| download_a:"", | |||
| downLoadSrc:'', | |||
| //单个项目参数 | |||
| @@ -652,7 +652,7 @@ | |||
| getAllProList(type_val,index){ | |||
| console.log("类型:"+type_val) | |||
| // console.log("类型:"+type_val) | |||
| this.dynamic = index | |||
| if (typeof type_val=="undefined" || type_val=="null" || type_val==""){ | |||
| this.params.type='' | |||
| @@ -665,7 +665,7 @@ | |||
| this.value_time=[] | |||
| } | |||
| this.$axios.get('../api/v1/projectboard/project',{ | |||
| this.$axios.get('../../api/v1/projectboard/project',{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| @@ -720,7 +720,7 @@ | |||
| }, | |||
| getOneProData(pro_id){ | |||
| this.$axios.get('../api/v1/projectboard/project/'+pro_id,{ | |||
| this.$axios.get('../../api/v1/projectboard/project/'+pro_id,{ | |||
| }).then((res)=>{ | |||
| this.tableDataIDTotal = res.data | |||
| this.tableDataContTop10=res.data.top10 | |||
| @@ -731,7 +731,7 @@ | |||
| }, | |||
| getOneProList(pro_id,type_val,bool_val,index){ | |||
| this.dynamic_pro=index | |||
| console.log("日期类型:"+type_val) | |||
| // console.log("日期类型:"+type_val) | |||
| if (typeof type_val=="undefined" || type_val=="null" || type_val==""){ | |||
| this.paramsID.type='' | |||
| this.paramsID.beginTime= this.formatDate(this.create_time_pro[0].getFullYear(),this.create_time_pro[0].getMonth() + 1,this.create_time_pro[0].getDate()) | |||
| @@ -743,7 +743,7 @@ | |||
| this.paramsID.endTime='' | |||
| } | |||
| this.paramsID.openi=bool_val | |||
| this.$axios.get('../api/v1/projectboard/project/'+pro_id+"/period",{ | |||
| this.$axios.get('../../api/v1/projectboard/project/'+pro_id+"/period",{ | |||
| params:this.paramsID | |||
| }).then((res)=>{ | |||
| if (bool_val){ | |||
| @@ -923,12 +923,24 @@ | |||
| type : 'category', | |||
| boundaryGap: false, | |||
| data : xdata_openI, | |||
| axisLine: { | |||
| show: false, //x轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| yAxis : [ | |||
| { | |||
| type : 'value', | |||
| axisLine: { | |||
| show: false, //x轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| @@ -1011,6 +1023,12 @@ | |||
| }, | |||
| legend: { | |||
| data:['浏览量','下载量','commit'], | |||
| selected:{ | |||
| // '浏览量':true, | |||
| // '下载量':true, | |||
| // 'commit':true, | |||
| } | |||
| // orient: 'vertical', | |||
| // top:'top', | |||
| }, | |||
| @@ -1029,12 +1047,24 @@ | |||
| { | |||
| type : 'category', | |||
| data : xdata, | |||
| axisLine: { | |||
| show: false, //x轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| yAxis : [ | |||
| { | |||
| type : 'value', | |||
| type : 'value', | |||
| axisLine: { | |||
| show: false, //x轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| series : [ | |||
| @@ -1059,6 +1089,16 @@ | |||
| ] | |||
| }; | |||
| // this.echartsSelectData.resize() | |||
| var checkboxs=document.getElementsByName('checkboxchart'); | |||
| for(var i=0; i<checkboxs.length; i++){ | |||
| // console.log("selectArr[i]:",this.option.legend.data[i]) | |||
| if(checkboxs[i].checked){ | |||
| this.option.legend.selected[this.option.legend.data[i]]=true; | |||
| }else{ | |||
| this.option.legend.selected[this.option.legend.data[i]]=false; | |||
| } | |||
| } | |||
| this.echartsSelectData.setOption(this.option) | |||
| // setTimeout(function (){ | |||
| // window.onresize = function () { | |||
| @@ -1299,6 +1339,9 @@ | |||
| /deep/ .el-range-separator{ | |||
| width: 20% !important; | |||
| } | |||
| /deep/ .el-pagination { | |||
| padding-bottom: 30px; | |||
| } | |||
| .colorChange { | |||
| background-color: #1684FC; | |||
| @@ -0,0 +1,903 @@ | |||
| <template> | |||
| <div class="el-col el-col-21" style="padding-right:10px "> | |||
| <div id='pro_tend' > | |||
| <div style="margin-top: 10px;"> | |||
| <b class="pro_item">增长趋势分析</b> <span class="update_time">数据更新时间:</span> <span style="font-size: 12px;">{{lastUpdatedTime}} / 从{{recordBeginTime}}开始统计</span> | |||
| </div> | |||
| <div style="margin-top:20px"> | |||
| <el-row> | |||
| <el-col :span='1' class ='item_list_first'> | |||
| <el-row class="item_title_h"> | |||
| | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| 昨天 | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| 累计 | |||
| </el-row> | |||
| </el-col> | |||
| <el-col span='23' > | |||
| <el-col :span='3' class ='item_list'> | |||
| <el-row class="item_title_h"> | |||
| 项目 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numReposAdd}} | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| {{ tableDataSummary.numRepos}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='3' > | |||
| <el-row class ='item_list_p item_title_h'> | |||
| 公开 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoPublicAdd}} | |||
| </el-row > | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoPublic}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='3' class ='item_list'> | |||
| <el-row class="item_title_h"> | |||
| 私有 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoPrivateAdd}} | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoPrivate}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='3'> | |||
| <el-row class ='item_list_p item_title_h'> | |||
| 自建 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoSelfAdd}} | |||
| </el-row > | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoSelf}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='3' > | |||
| <el-row class ='item_list_p item_title_h'> | |||
| 派生 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoForkAdd}} | |||
| </el-row > | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoFork}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='3' class ='item_list '> | |||
| <el-row class="item_title_h"> | |||
| 镜像 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoMirrorAdd}} | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoMirror}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='3'> | |||
| <el-row class ='item_list_p item_title_h'> | |||
| 组织 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoOrgAdd}} | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoOrg}} | |||
| </el-row> | |||
| </el-col> | |||
| <el-col :span='2'> | |||
| <el-row class="item_title_h"> | |||
| 个人 | |||
| </el-row> | |||
| <el-row class="item_h num_color"> | |||
| {{tableDataSummary.numRepoNotOrgAdd}} | |||
| </el-row> | |||
| <el-row class="item_h"> | |||
| {{tableDataSummary.numRepoNotOrg}} | |||
| </el-row> | |||
| </el-col> | |||
| </el-col> | |||
| </el-row> | |||
| </div> | |||
| <div style="margin-top: 20px;"> | |||
| <span class="sta_iterm">统计周期:</span> | |||
| <!-- <button type="button" class='btnFirst' id ="yesterday" v-bind:class="{colorChange:1==dynamic}" @click="resetPage(),getPeriodProList('yesterday',1)">昨天</button> --> | |||
| <button type="button" class='btn' id = "current_week" v-bind:class="{colorChange:1==dynamic}" @click="resetPage(),getPeriodProList('current_week',1)">本周</button> | |||
| <button type="button" class='btn' id = "current_month" v-bind:class="{colorChange:2==dynamic}" @click="resetPage(),getPeriodProList('current_month',2)">本月</button> | |||
| <button type="button" class='btn' id = "last_month" v-bind:class="{colorChange:3==dynamic}" @click="resetPage(),getPeriodProList('last_month',3)">上月</button> | |||
| <button type="button" class='btn' id = "monthly" v-bind:class="{colorChange:4==dynamic}" @click="resetPage(),getPeriodProList('monthly',4)">近30天</button> | |||
| <button type="button" class='btn' id = "current_year" v-bind:class="{colorChange:5==dynamic}" @click="resetPage(),getPeriodProList('current_year',5)">今年</button> | |||
| <button type="button" class='btnLast' id = "all" v-bind:class="{colorChange:6==dynamic}" @click="resetPage(),getPeriodProList('all',6)">所有</button> | |||
| <span style="margin-left: 20px;"> | |||
| <el-date-picker | |||
| v-model="value_time" | |||
| prefix-icon="el-icon-time" | |||
| @change="resetPage(),getPeriodProList('',0)" | |||
| type="daterange" | |||
| size='small' | |||
| range-separator="至" | |||
| start-placeholder="开始日期" | |||
| end-placeholder="结束日期"> | |||
| </el-date-picker> | |||
| </span> | |||
| <span style="float:right; margin-right: 20px;"> | |||
| <div style="display:inline-block;margin-left: 20px; "> | |||
| <a class="el-icon-download" v-if="tableData!=''" :href= "'../../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'" ></a> | |||
| <i class="el-icon-download" v-else="tableData=''" href="#" style="color:rgba(187, 187, 187, 100);" @click='popMark()'></i> | |||
| <!-- <span ><a id = "download_file" :href= "'../api/v1/projectboard/downloadAll/?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime+'&q='+this.params.q+'&sort=openi'" >下载报告</a> </span> --> | |||
| <span > | |||
| <a id = "download_file" v-if="tableData!=''" :href= "'../../api/v1/projectboard/summary/download?type='+this.params.type+'&beginTime='+this.params.beginTime+'&endTime='+this.params.endTime">下载报告</a> | |||
| <a id = "download_file" v-else="tableData=''" href= "#" style="color:rgba(187, 187, 187, 100);" @click='popMark()'>下载报告</a> | |||
| </span> | |||
| </div> | |||
| </span> | |||
| </div> | |||
| <div class="item_echart" id ='linecharts'> | |||
| <div style="margin: 15px 10px 30px;"> | |||
| <label for="label" @change='clickCheckBox'> | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" checked="checked" value="新增项目"/> 新增项目 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" checked="checked" value="新增公开项目"/>新增公开项目 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" checked="checked" value="新增私有项目"/>新增私有项目 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="新增自建项目"/>新增自建项目 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="新增派生项目"/>新增派生项目 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="新增镜像项目"/>新增镜像项目 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="累计项目"/>累计项目 | |||
| </label> | |||
| </div> | |||
| <div id ="selectData" style="height: 300px;"> | |||
| </div> | |||
| </div> | |||
| <div style="margin-top: 30px;"> | |||
| <el-table | |||
| :data="tableData.slice((page-1)*pageSize,page*pageSize)" | |||
| style="width: 100%" | |||
| :header-cell-style="tableHeaderStyle" | |||
| :cell-style='cellStyle'> | |||
| <el-table-column | |||
| label="日期" | |||
| align="left" | |||
| prop="creatTime" | |||
| > | |||
| </el-table-column> | |||
| <el-table-column | |||
| label="新增项目" | |||
| align="center" | |||
| prop="numReposAdd" | |||
| > | |||
| </el-table-column> | |||
| <el-table-column | |||
| label="累计项目" | |||
| align="center" | |||
| prop="numRepos" | |||
| > | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="numRepoPublicAdd" | |||
| label="新增公开项目" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="numRepoPrivateAdd" | |||
| label="新增私有项目" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="numRepoSelfAdd" | |||
| label="新增自建项目" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="numRepoForkAdd" | |||
| label="新增派生项目" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="numRepoMirrorAdd" | |||
| label="新增镜像项目" | |||
| align="center"> | |||
| </el-table-column> | |||
| </el-table> | |||
| </div> | |||
| <div style="margin-top:50px;text-align:center"> | |||
| <el-pagination | |||
| background | |||
| @size-change="handleSizeChange" | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-size="pageSize" | |||
| :page-sizes="[5,10,20]" | |||
| layout="total, sizes,prev, pager, next,jumper" | |||
| :total="tableData.length"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| // import barLabel from './basic/barLabel.vue'; | |||
| const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | |||
| import { export2Excel } from '../excel/util.js' | |||
| export default{ | |||
| name:'ProAnalysis', | |||
| components: { | |||
| // barLabel, | |||
| }, | |||
| data() { | |||
| return { | |||
| recordBeginTime:'', | |||
| lastUpdatedTime:'', | |||
| page:1, | |||
| pageSize:10, | |||
| params:{type:'monthly',page:1,pagesize:10,beginTime:'',endTime:''}, | |||
| tableData: [], | |||
| tableDataSummary:{}, | |||
| totalPage:0, | |||
| totalNum:0, | |||
| pickerOptions: { | |||
| }, | |||
| value_time: '', | |||
| dynamic:4, | |||
| echartsSelectData:'', | |||
| option:'', | |||
| }; | |||
| }, | |||
| methods: { | |||
| // download_file(){ | |||
| // this.params.type='all' | |||
| // }, | |||
| popMark(){ | |||
| alert("数据为空时,不能下载!") | |||
| }, | |||
| exportData(){ | |||
| // this.getOneProList(this.pro_id,'all',true,7) | |||
| // this.getOneProList(this.pro_id,'all',false,7) | |||
| // this.fileName() | |||
| if (this.tableData!=''){ | |||
| this.page=1 | |||
| var saveFileName = this.getFileName() | |||
| export2Excel(this.columns,this.tableData,saveFileName) | |||
| }else{ | |||
| alert("数据为空时,不能下载!") | |||
| } | |||
| }, | |||
| getFileName(){ | |||
| var now = new Date(); // 当前日期 | |||
| var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | |||
| var nowDay = now.getDate(); // 当前日 | |||
| var nowMonth = now.getMonth(); // 当前月 | |||
| var nowYear = now.getFullYear(); // 当前年 | |||
| var today = this.saveFormatDate(nowYear,nowMonth+1,nowDay); | |||
| var tmp = new Date(now.setTime(now.getTime()-24*60*60*1000)); | |||
| var yesterday = this.saveFormatDate(tmp.getFullYear(),tmp.getMonth()+1,tmp.getDate()); | |||
| var yesterday_tmp = this.formatDate(tmp.getFullYear(),tmp.getMonth()+1,tmp.getDate()) | |||
| var startDate='' | |||
| var endDate='' | |||
| var saveFileName = '' | |||
| if (typeof this.paramsID.type=="undefined" || this.paramsID.type=="null" || this.paramsID.type==""){ | |||
| // startDate= this.saveFormatDate(this.create_time_pro[0].getFullYear(),this.create_time_pro[0].getMonth() + 1,this.create_time_pro[0].getDate()); | |||
| endDate = this.saveFormatDate(this.create_time_pro[1].getFullYear(),this.create_time_pro[1].getMonth() + 1,this.create_time_pro[1].getDate()); | |||
| var tmp = this.formatDate(this.create_time_pro[0].getFullYear(),this.create_time_pro[0].getMonth() + 1,this.create_time_pro[0].getDate()) | |||
| startDate = this.comparedate(tmp,this.recordBeginTime) | |||
| console.log("comparedate:"+startDate) | |||
| saveFileName = this.alias+"_"+startDate+'_'+endDate | |||
| }else{ | |||
| switch(this.paramsID.type){ | |||
| case "yesterday":{ | |||
| startDate = this.comparedate(yesterday_tmp,this.recordBeginTime) | |||
| endDate = startDate | |||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||
| break | |||
| } | |||
| case "current_week":{ | |||
| var now = new Date(); // 当前日期 | |||
| var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | |||
| var day = nowDayOfWeek || 7; | |||
| startDate = this.formatDate(now.getFullYear(), nowMonth+1, nowDay + 1 - day); | |||
| startDate = this.comparedate(startDate,this.recordBeginTime) | |||
| endDate = yesterday | |||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||
| break | |||
| } | |||
| case "current_month":{ | |||
| startDate = this.formatDate(nowYear,nowMonth+1,1); | |||
| startDate = this.comparedate(startDate,this.recordBeginTime) | |||
| endDate = yesterday | |||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||
| break | |||
| } | |||
| case "last_month":{ | |||
| let lastMonthDate = new Date(); // 上月日期 | |||
| lastMonthDate.setDate(1); | |||
| lastMonthDate.setMonth(lastMonthDate.getMonth()-1); | |||
| let lastYear = lastMonthDate.getFullYear(); | |||
| let lastMonth = lastMonthDate.getMonth(); | |||
| startDate=this.formatDate(lastYear, lastMonth+1, 1); | |||
| startDate = this.comparedate(startDate,this.recordBeginTime) | |||
| var monthStartDate = new Date(lastYear, lastMonth, 1); | |||
| var monthEndDate = new Date(lastYear, lastMonth+1, 1); | |||
| var days = (monthEndDate - monthStartDate) / (1000 * 60 * 60 * 24) | |||
| endDate=this.saveFormatDate(lastYear, lastMonth+1, days); //月份从0开始,所以+1保存月份 | |||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||
| break | |||
| } | |||
| case "monthly":{ | |||
| var temp=new Date(now - 1000 * 60 * 60 * 24 * 30) | |||
| startDate = this.formatDate(temp.getFullYear(),temp.getMonth()+1,temp.getDate()); | |||
| startDate = this.comparedate(startDate,this.recordBeginTime) | |||
| endDate = yesterday | |||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||
| break | |||
| } | |||
| case "current_year":{ | |||
| startDate = this.formatDate(now.getFullYear(), 1, 1); | |||
| startDate = this.comparedate(startDate,this.recordBeginTime) | |||
| endDate = yesterday | |||
| saveFileName = this.alias+"_"+startDate+'_'+ endDate | |||
| break | |||
| } | |||
| case "all":{ | |||
| console.log("e:"+today) | |||
| startDate = 'all' | |||
| endDate = yesterday | |||
| saveFileName = this.alias+'_所有' | |||
| break | |||
| } | |||
| } | |||
| } | |||
| return saveFileName | |||
| }, | |||
| resetPage(){ | |||
| this.page=1 | |||
| this.params.page = 1 | |||
| }, | |||
| resetCurrentPage(){ | |||
| this.page=1 | |||
| }, | |||
| handleSizeChange(val){ | |||
| this.pageSize = val | |||
| }, | |||
| handleCurrentChange(val){ | |||
| this.page = val; | |||
| }, | |||
| saveFormatDate(myyear,mymonth,myweekday) { | |||
| // var myyear = this.date.getFullYear(); | |||
| // var mymonth = this.date.getMonth() + 1; | |||
| // var myweekday = this.date.getDate(); | |||
| if (mymonth < 10) { | |||
| mymonth = "0" + mymonth; | |||
| } | |||
| if (myweekday < 10) { | |||
| myweekday = "0" + myweekday; | |||
| } | |||
| console.log((myyear +''+ mymonth +''+ myweekday)) | |||
| return (myyear +''+ mymonth +''+ myweekday); | |||
| }, | |||
| formatDate(myyear,mymonth,myweekday) { | |||
| // var myyear = this.date.getFullYear(); | |||
| // var mymonth = this.date.getMonth() + 1; | |||
| // var myweekday = this.date.getDate(); | |||
| if (mymonth < 10) { | |||
| mymonth = "0" + mymonth; | |||
| } | |||
| if (myweekday < 10) { | |||
| myweekday = "0" + myweekday; | |||
| } | |||
| return (myyear +'-'+ mymonth +'-'+ myweekday); | |||
| }, | |||
| //获得某月的天数 | |||
| getPeriodProList(type_val,index){ | |||
| // console.log("类型:"+type_val) | |||
| this.dynamic = index | |||
| if (typeof type_val=="undefined" || type_val=="null" || type_val==""){ | |||
| this.params.type='' | |||
| this.params.beginTime=this.formatDate(this.value_time[0].getFullYear(),this.value_time[0].getMonth() + 1,this.value_time[0].getDate()) | |||
| this.params.endTime=this.formatDate(this.value_time[1].getFullYear(),this.value_time[1].getMonth() + 1,this.value_time[1].getDate()) | |||
| }else{ | |||
| this.params.type=type_val | |||
| this.params.beginTime='' | |||
| this.params.endTime='' | |||
| this.value_time=[] | |||
| } | |||
| // console.log("params:",this.params) | |||
| this.$axios.get('../../api/v1/projectboard/summary/period',{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| this.recordBeginTime=res.data.recordBeginTime | |||
| // this.lastUpdatedTime=res.data.creatTime | |||
| this.tableData = res.data.pageRecords | |||
| this.totalPage=res.data.totalPage | |||
| // this.totalNum = res.data.totalCount//this.totalPage*this.params.pagesize | |||
| // console.log("res.data:"+res.data) | |||
| this.drawSelectData() | |||
| }) | |||
| }, | |||
| getSummaryPro(){ | |||
| this.$axios.get('../../api/v1/projectboard/summary',{ | |||
| }).then((res)=>{ | |||
| this.tableDataSummary = res.data | |||
| this.lastUpdatedTime = res.data.creatTime | |||
| }) | |||
| }, | |||
| tableHeaderStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex===0){ | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| cellStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex%2 === 1){ | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| drawSelectData(){ | |||
| // $("#selectData").removeAttr("selectData").empty(); | |||
| var xdata=[] | |||
| var ydata_add_pro=[] | |||
| var ydata_add_public_pro=[] | |||
| var ydata_add_private_pro=[] | |||
| var ydata_add_self=[] | |||
| var ydata_add_fork=[] | |||
| var ydata_add_mirror=[] | |||
| var ydata_cumulative_pro=[] | |||
| // if () | |||
| for(var i =0;i<this.tableData.length;i++){ | |||
| xdata.push(this.tableData[this.tableData.length-1-i].creatTime); | |||
| ydata_add_pro.push(this.tableData[this.tableData.length-1-i].numReposAdd) | |||
| ydata_add_public_pro.push(this.tableData[this.tableData.length-1-i].numRepoPublicAdd) | |||
| ydata_add_private_pro.push(this.tableData[this.tableData.length-1-i].numRepoPrivateAdd) | |||
| ydata_add_self.push(this.tableData[this.tableData.length-1-i].numRepoSelfAdd) | |||
| ydata_add_fork.push(this.tableData[this.tableData.length-1-i].numRepoForkAdd) | |||
| ydata_add_mirror.push(this.tableData[this.tableData.length-1-i].numRepoMirrorAdd) | |||
| ydata_cumulative_pro.push(this.tableData[this.tableData.length-1-i].numRepos) | |||
| } | |||
| // console.log("ydata_openI:"+ydata_add_pro) | |||
| // console.log(xdata) | |||
| this.option = { | |||
| title : { | |||
| text: '', | |||
| textStyle: { | |||
| fontSize: 12, | |||
| }, | |||
| left:'center', | |||
| top:'bottom', | |||
| subtext: '', | |||
| }, | |||
| tooltip : { | |||
| trigger: 'axis', | |||
| backgroundColor:'rgba(255,255,255,0.8)', | |||
| color:'black', | |||
| borderWidth:'1', | |||
| borderColor:'gray', | |||
| textStyle:{ | |||
| color:'black' | |||
| }, | |||
| }, | |||
| legend: { | |||
| data:['新增项目','新增公开项目','新增私有项目','新增自建项目','新增派生项目','新增镜像项目','累计项目'], | |||
| selected:{ | |||
| // '新增项目':true, | |||
| // '新增公开项目':true, | |||
| // '新增私有项目':true, | |||
| // '新增自建项目':false, | |||
| // '新增派生项目':false, | |||
| // '新增镜像项目':false, | |||
| // '累计项目':false | |||
| } | |||
| // orient: 'vertical', | |||
| // top:'top', | |||
| }, | |||
| toolbox: { | |||
| show : false, | |||
| feature : { | |||
| mark : {show: true}, | |||
| dataView : {show: false, readOnly: false}, | |||
| magicType : {show: true, type: ['line', 'bar']}, | |||
| restore : {show: false}, | |||
| saveAsImage : {show: true} | |||
| } | |||
| }, | |||
| calculable : true, | |||
| xAxis : [ | |||
| { | |||
| type : 'category', | |||
| data : xdata, | |||
| axisLine: { | |||
| show: false, //x轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| yAxis : [ | |||
| { | |||
| type : 'value', | |||
| axisLine: { | |||
| show: false, //y轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| series : [ | |||
| { name:"新增项目", | |||
| data: ydata_add_pro, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#3894FF", | |||
| }, | |||
| color:"#3894FF", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增公开项目", | |||
| data: ydata_add_public_pro, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#67B3BB", | |||
| }, | |||
| color:"#67B3BB", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增私有项目", | |||
| data: ydata_add_private_pro, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#58A55C", | |||
| }, | |||
| color:"#58A55C", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增自建项目", | |||
| data: ydata_add_self, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#F2BD42", | |||
| }, | |||
| color:"#F2BD42", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增派生项目", | |||
| data: ydata_add_fork, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#DAA67B", | |||
| }, | |||
| color:"#DAA67B", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增镜像项目", | |||
| data: ydata_add_mirror, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#2E4552", | |||
| }, | |||
| color:"#2E4552", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"累计项目", | |||
| data: ydata_cumulative_pro, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#4786B4", | |||
| }, | |||
| color:"#4786B4", | |||
| } | |||
| }, | |||
| }, | |||
| ] | |||
| }; | |||
| // this.echartsSelectData.resize() | |||
| var checkboxs=document.getElementsByName('checkboxchart'); | |||
| for(var i=0; i<checkboxs.length; i++){ | |||
| // console.log("selectArr[i]:",this.option.legend.data[i]) | |||
| if(checkboxs[i].checked){ | |||
| this.option.legend.selected[this.option.legend.data[i]]=true; | |||
| }else{ | |||
| this.option.legend.selected[this.option.legend.data[i]]=false; | |||
| } | |||
| } | |||
| this.echartsSelectData.setOption(this.option) | |||
| // setTimeout(function (){ | |||
| // window.onresize = function () { | |||
| // this.echartsSelectData.resize; | |||
| // } | |||
| // },200) | |||
| // // 使用刚指定的选择项数据显示图表。 | |||
| // var selectArr = this.echartsSelectData.getOption().legend[0].data;//legend所有值 | |||
| // var checkboxs=document.getElementsByName('checkboxchart'); | |||
| // $(".checkboxchart").click(function(){ | |||
| // var obj = {}; | |||
| // for(var i=0; i<checkboxs.length; i++){ | |||
| // if(checkboxs[i].checked){ | |||
| // obj[selectArr[i]] = true; | |||
| // }else{ | |||
| // obj[selectArr[i]] = false; | |||
| // } | |||
| // } | |||
| // option.legend.selected = obj; | |||
| // this.echartsSelectData.setOption(option); | |||
| // }); | |||
| }, | |||
| clickCheckBox(){ | |||
| // 使用刚指定的选择项数据显示图表。 | |||
| var selectArr = this.echartsSelectData.getOption().legend[0].data;//legend所有值 | |||
| var checkboxs=document.getElementsByName('checkboxchart'); | |||
| // $(".checkboxchart").click(function(){ | |||
| var obj = {}; | |||
| for(var i=0; i<checkboxs.length; i++){ | |||
| if(checkboxs[i].checked){ | |||
| obj[selectArr[i]] = true; | |||
| }else{ | |||
| obj[selectArr[i]] = false; | |||
| } | |||
| } | |||
| this.option.legend.selected = obj; | |||
| this.echartsSelectData.setOption(this.option); | |||
| // }); | |||
| }, | |||
| comparedate(date1,date2){ | |||
| // console.log("date1:"+date1) | |||
| // console.log("date1:"+date2) | |||
| var oDate1 = new Date(date1); | |||
| var oDate2 = new Date(date2); | |||
| if(oDate1.getTime() < oDate2.getTime()){ | |||
| var data = date2.split('-') | |||
| return data[0]+''+data[1]+''+data[2] | |||
| } else { | |||
| var data = date1.split('-') | |||
| return data[0]+''+data[1]+''+data[2] | |||
| } | |||
| }, | |||
| }, | |||
| filters:{ | |||
| }, | |||
| mounted() { | |||
| this.getPeriodProList("monthly",4); | |||
| this.getSummaryPro(); | |||
| document.getElementById('selectData').style.width = document.getElementById('pro_tend').offsetWidth*0.8+'px' | |||
| this.echartsSelectData = this.$echarts.init(document.getElementById('selectData')) | |||
| }, | |||
| watch:{ | |||
| }, | |||
| created() { | |||
| this.getSummaryPro(); | |||
| this.getPeriodProList("monthly",4); | |||
| }, | |||
| updated(){ | |||
| if(document.querySelectorAll('img[avatar]').length!==0){ | |||
| window.LetterAvatar.transform() | |||
| } | |||
| } | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| .item_list_first{ | |||
| border-right: 1px solid rgba(219,219,219,100); | |||
| padding-right: 10px; | |||
| } | |||
| .item_list{ | |||
| border-right: 1px solid rgba(219,219,219,100); | |||
| padding:0px 10px; | |||
| } | |||
| .item_list_p{ | |||
| border-right: 1px solid rgba(219,219,219,100); | |||
| padding:0px 10px; | |||
| } | |||
| .item_h{ | |||
| line-height: 40px; | |||
| text-align: center; | |||
| } | |||
| .item_title_h{ | |||
| line-height: 28px; | |||
| text-align: center; | |||
| } | |||
| .num_color{ | |||
| color: #0366D6; | |||
| font-weight: bold; | |||
| } | |||
| .pro_item{ | |||
| font-size: 16px; | |||
| color: rgba(16, 16, 16, 100); | |||
| font-family: SourceHanSansSC-bold; | |||
| } | |||
| .sta_item{ | |||
| font-size: 14px; | |||
| color: rgb(0 0 0); | |||
| font-family: SourceHanSansSC-bold; | |||
| } | |||
| .update_time{ | |||
| line-height: 17px; | |||
| font-size: 12px; | |||
| color:rgba(187, 187, 187, 100); | |||
| margin-left: 10px; | |||
| } | |||
| .btnFirst{ | |||
| line-height: 1.5; | |||
| margin: -3.5px; | |||
| border: 1px solid rgba(22, 132, 252, 100); | |||
| border-right: none; | |||
| background: #FFFF; | |||
| color: #1684FC; | |||
| width: 60px; | |||
| height: 30px; | |||
| border-radius:4px 0px 0px 4px; | |||
| } | |||
| .btn{ | |||
| line-height: 1.5; | |||
| margin: -3.5px; | |||
| border: 1px solid rgba(22, 132, 252, 100); | |||
| border-right: none; | |||
| background: #FFFF; | |||
| color: #1684FC; | |||
| width: 60px; | |||
| height: 30px; | |||
| } | |||
| .btnLast{ | |||
| line-height: 1.5; | |||
| margin: -3.5px; | |||
| border: 1px solid rgba(22, 132, 252, 100); | |||
| /* border-right: none; */ | |||
| background: #FFFF; | |||
| color: #1684FC; | |||
| width: 60px; | |||
| height: 30px; | |||
| border-radius:0px 4px 4px 0px; | |||
| } | |||
| .btnFirst, .btn, .btnLast { | |||
| cursor: pointer; | |||
| } | |||
| /deep/ .el-table tbody tr:hover>td { | |||
| background-color:#D3D3D3!important; | |||
| opacity:1 | |||
| } | |||
| /deep/ .el-table { | |||
| font-size: 12px; | |||
| } | |||
| /deep/ .el-range-separator{ | |||
| width: 20% !important; | |||
| } | |||
| /deep/ .el-pagination { | |||
| padding-bottom: 30px; | |||
| } | |||
| .colorChange { | |||
| background-color: #1684FC; | |||
| color: #FFFF; | |||
| cursor: default; | |||
| } | |||
| .items{ | |||
| text-align: center; | |||
| border-right:1px solid rgba(219, 219, 219, 100); | |||
| } | |||
| .item_l{ | |||
| margin-right: 5px; | |||
| border:1px solid rgba(219, 219, 219, 100); | |||
| height: 370px; | |||
| width: 100%; | |||
| } | |||
| .item_r{ | |||
| margin-right:5px; | |||
| border:1px solid rgba(219, 219, 219, 100); | |||
| height: 370px; | |||
| overflow:auto | |||
| } | |||
| .item_echart{ | |||
| margin-top: 10px; | |||
| margin-right: 5px; | |||
| border:1px solid rgba(219, 219, 219, 100); | |||
| height: 350px; | |||
| width: 100%; | |||
| } | |||
| .item_content{ | |||
| color:#0366D6; | |||
| margin-top: 10px; | |||
| font-weight:bold; | |||
| } | |||
| </style> | |||
| @@ -1,7 +1,7 @@ | |||
| <template> | |||
| <div> | |||
| <div class="el-col el-col-21" style="padding-right:10px"> | |||
| <div style="margin-top: 10px;"> | |||
| <b class="pro_item">用户分析</b> <span class="update_time">数据更新时间:</span><span style="font-size: 12px;">{{lastUpdatedTime}}  / 从{{recordBeginTime}}开始统计</span> | |||
| <b class="pro_item">活动分析</b> <span class="update_time">数据更新时间:</span><span style="font-size: 12px;">{{lastUpdatedTime}}  / 从{{recordBeginTime}}开始统计</span> | |||
| </div> | |||
| <div style="margin-top: 20px;"> | |||
| <span class="sta_iterm">统计周期:</span> | |||
| @@ -54,12 +54,13 @@ | |||
| > | |||
| </el-table-column> | |||
| <el-table-column | |||
| fixed | |||
| label="用户名" | |||
| align="left" | |||
| prop="Name" | |||
| width="100px"> | |||
| <template slot-scope="scope"> | |||
| <a :href="AppSubUrl +'../../../'+ scope.row.Name">{{scope.row.Name}} </a> | |||
| <a :href="AppSubUrl +'../../../../'+ scope.row.Name">{{scope.row.Name}} </a> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| @@ -259,7 +260,7 @@ | |||
| params:{startDate:'',endDate:'',page:1,pageSize:10,userName:''}, | |||
| tableData: [], | |||
| totalNum:0, | |||
| dataUrl:'../api/v1/query_user_static_page', | |||
| dataUrl:'../../api/v1/query_user_static_page', | |||
| pickerOptions: { | |||
| }, | |||
| value_time: '', | |||
| @@ -334,7 +335,7 @@ | |||
| return days; | |||
| }, | |||
| getUpdateTime(){ | |||
| this.$axios.get('../api/v1/projectboard/project',{ | |||
| this.$axios.get('../../api/v1/projectboard/project',{ | |||
| params:this.params_pro | |||
| }).then((res)=>{ | |||
| this.recordBeginTime=res.data.recordBeginTime | |||
| @@ -357,7 +358,7 @@ | |||
| let lastYear = lastMonthDate.getYear(); | |||
| let lastMonth = lastMonthDate.getMonth(); | |||
| this.dataUrl = '../api/v1/query_user_static_page'; | |||
| this.dataUrl = '../../api/v1/query_user_static_page'; | |||
| if (typeof type_val=="undefined" || type_val=="null" || type_val==""){ | |||
| this.params.startDate= this.formatDate(this.value_time[0].getFullYear(),this.value_time[0].getMonth() + 1,this.value_time[0].getDate()); | |||
| @@ -366,37 +367,37 @@ | |||
| switch(type_val){ | |||
| case "yesterday_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_yesterday'; | |||
| this.dataUrl = '../../api/v1/query_user_yesterday'; | |||
| break | |||
| } | |||
| case "current_week_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_current_week'; | |||
| this.dataUrl = '../../api/v1/query_user_current_week'; | |||
| break | |||
| } | |||
| case "current_month_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_current_month'; | |||
| this.dataUrl = '../../api/v1/query_user_current_month'; | |||
| break | |||
| } | |||
| case "last_month_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_last_month'; | |||
| this.dataUrl = '../../api/v1/query_user_last_month'; | |||
| break | |||
| } | |||
| case "monthly_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_last30_day'; | |||
| this.dataUrl = '../../api/v1/query_user_last30_day'; | |||
| break | |||
| } | |||
| case "current_year_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_current_year'; | |||
| this.dataUrl = '../../api/v1/query_user_current_year'; | |||
| break | |||
| } | |||
| case "all_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../api/v1/query_user_all'; | |||
| this.dataUrl = '../../api/v1/query_user_all'; | |||
| break | |||
| } | |||
| } | |||
| @@ -561,7 +562,9 @@ | |||
| /deep/ .el-range-separator{ | |||
| width: 20% !important; | |||
| } | |||
| /deep/ .el-pagination { | |||
| padding-bottom: 30px; | |||
| } | |||
| .colorChange { | |||
| background-color: #1684FC; | |||
| color: #FFFF; | |||
| @@ -0,0 +1,949 @@ | |||
| <template> | |||
| <div class="el-col el-col-21" style="padding-right:10px"> | |||
| <div id='user_tend'> | |||
| <div style="margin-top: 10px;"> | |||
| <b class="pro_item">增长趋势分析</b> <span class="update_time">数据更新时间:</span><span style="font-size: 12px;">{{lastUpdatedTime}}  / 从{{recordBeginTime}}开始统计</span> | |||
| </div> | |||
| <div id = 'isShow'> | |||
| <el-col :span="11"> | |||
| <el-col id="ys_add_user" class="draw_region"> | |||
| </el-col> | |||
| <el-col :span="8" :style="{ height: '180px'}" v-if="ys_count>0"> | |||
| <span class="yesterday_blk yesterday_title" >昨日新增注册用户数 </span> | |||
| <span class="yesterday_blk yesterday_color1 yesterday_pdrt yesterday_text">未激活:<span class="bold_num">{{ tableDataYesterday.NotActivateRegistUser }}</span> 人 </span> | |||
| <span class="yesterday_blk yesterday_color2 yesterday_pdrt yesterday_text">已激活: <span class="bold_num">{{ tableDataYesterday.ActivateRegistUser }} </span>人</span> | |||
| <span class="yesterday_blk yesterday_pdrt yesterday_text">有贡献活动: <span class="bold_num">{{ tableDataYesterday.HasActivityUser }} </span>人</span> | |||
| </el-col> | |||
| </el-col> | |||
| <el-col :span="13"> | |||
| <el-col id="ys_all_user" class="draw_region"> | |||
| </el-col> | |||
| <el-col :span="8" :style="{ height: '180px'}" v-if="ys_count>0"> | |||
| <span class="yesterday_blk yesterday_title" >注册用户数 </span> | |||
| <span class="yesterday_blk yesterday_color2 yesterday_pdrt yesterday_text">未激活:<span class="bold_num">{{ tableDataYesterday.TotalNotActivateRegistUser }} </span>人</span> | |||
| <span class="yesterday_blk yesterday_color1 yesterday_pdrt yesterday_text">已激活:<span class="bold_num">{{ tableDataYesterday.TotalActivateRegistUser}} </span>人 </span> | |||
| <span class="yesterday_blk yesterday_pdrt yesterday_text">有贡献活动:<span class="bold_num"> {{ tableDataYesterday.TotalHasActivityUser}} </span>人</span> | |||
| </el-col> | |||
| </el-col> | |||
| </div> | |||
| <div style="margin-top: 20px;"> | |||
| <span class="sta_iterm">统计周期:</span> | |||
| <button type="button" class='btn' id = "current_week_usr" v-bind:class="{colorChange:1==dynamic}" @click="resetPage(),getUserList('current_week_usr',1)">本周</button> | |||
| <button type="button" class='btn' id = "current_month_usr" v-bind:class="{colorChange:2==dynamic}" @click="resetPage(),getUserList('current_month_usr',2)">本月</button> | |||
| <button type="button" class='btn' id = "last_month_usr" v-bind:class="{colorChange:3==dynamic}" @click="resetPage(),getUserList('last_month_usr',3)">上月</button> | |||
| <button type="button" class='btn' id = "monthly_usr" v-bind:class="{colorChange:4==dynamic}" @click="resetPage(),getUserList('monthly_usr',4)">近30天</button> | |||
| <button type="button" class='btn' id = "current_year_usr" v-bind:class="{colorChange:5==dynamic}" @click="resetPage(),getUserList('current_year_usr',5)">今年</button> | |||
| <button type="button" class='btnLast' id = "all_usr" v-bind:class="{colorChange:6==dynamic}" @click="resetPage(),getUserList('all_usr',6)">所有</button> | |||
| <span style="margin-left: 20px;"> | |||
| <el-date-picker | |||
| v-model="value_time" | |||
| prefix-icon="el-icon-time" | |||
| @change="resetPage(),getUserList('',0)" | |||
| type="daterange" | |||
| size='small' | |||
| unlink-panels | |||
| range-separator="至" | |||
| start-placeholder="开始日期" | |||
| end-placeholder="结束日期"> | |||
| </el-date-picker> | |||
| </span> | |||
| <span style="float:right; margin-right: 20px;" > | |||
| <a style="display:inline-block;margin-left: 20px; " id = 'download'> | |||
| <a class="el-icon-download" v-if="tableData!=''" :href= "this.dataUrl + '?startDate='+this.params.startDate+'&endDate='+this.params.endDate+'&IsReturnFile=true' " ></a> | |||
| <i class="el-icon-download" v-else="tableData=''" href="#" style="color:rgba(187, 187, 187, 100);" @click='popMark()'></i> | |||
| <span > | |||
| <a v-if="tableData!=''" :href= "this.dataUrl + '?startDate='+this.params.startDate+'&endDate='+this.params.endDate+'&IsReturnFile=true' " >下载报告</a> | |||
| <a v-else="tableData=''" href= "#" style="color:rgba(187, 187, 187, 100);" @click='popMark()'>下载报告</a> | |||
| </span> | |||
| </a> | |||
| <!-- <span style="display:inline-block;margin-left: 20px; "> | |||
| <el-input size="small" placeholder="输入用户名搜索" v-model="search" class="input-with-select" @keyup.enter.native="searchName() "><i slot="suffix" class="el-input__icon el-icon-search" @click="searchName() "></i> | |||
| </el-input> | |||
| </span> --> | |||
| </span> | |||
| </div> | |||
| <div class="item_echart" id ='linecharts'> | |||
| <div style="margin: 15px 10px 30px;"> | |||
| <label for="label" @change='clickCheckBox'> | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" checked="checked" value="新增项目"/> 新增注册用户 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" checked="checked" value="新增公开项目"/>新增已激活 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" checked="checked" value="新增私有项目"/>新增有贡献活动 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="新增自建项目"/>新增未激活 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="新增派生项目"/>累计注册用户 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="新增镜像项目"/>累计已激活 | |||
| <input type="checkbox" class="checkboxchart" name="checkboxchart" value="累计项目"/>累计有贡献活动 | |||
| </label> | |||
| </div> | |||
| <div id ="selectData" style="height: 300px;"> | |||
| </div> | |||
| </div> | |||
| <div style="margin-top: 30px;"> | |||
| <el-table | |||
| :data="tableData.slice((page-1)*pageSize,page*pageSize)" | |||
| style="width: 100%" | |||
| :header-cell-style="tableHeaderStyle" | |||
| :cell-style='cellStyle'> | |||
| <el-table-column | |||
| label="日期" | |||
| prop="DisplayDate" | |||
| align="center" | |||
| stripe | |||
| > | |||
| </el-table-column> | |||
| <el-table-column | |||
| label="新增注册用户" | |||
| prop="TotalRegistUser" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="ActivateRegistUser" | |||
| label="新增已激活" | |||
| width="120px" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="HasActivityUser" | |||
| label="新增有贡献活动" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="NotActivateRegistUser" | |||
| label="新增未激活" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="ActivateIndex" | |||
| label="新增用户激活率" | |||
| align="center"> | |||
| <template slot-scope="scope"> | |||
| {{scope.row.ActivateIndex | rounding}} | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="TotalUser" | |||
| label="累计注册用户" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="TotalActivateRegistUser" | |||
| label="累计已激活" | |||
| align="center"> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="TotalHasActivityUser" | |||
| label="累计有贡献活动" | |||
| align="center"> | |||
| </el-table-column> | |||
| </el-table> | |||
| </div> | |||
| <div style="margin-top:50px;text-align:center"> | |||
| <el-pagination | |||
| background | |||
| @size-change="handleSizeChange" | |||
| @current-change="handleCurrentChange" | |||
| :current-page="page" | |||
| :page-size="pageSize" | |||
| :page-sizes="[5,10,20]" | |||
| layout="total, sizes, prev, pager, next,jumper" | |||
| :total="tableData.length"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { export2Excel } from '../excel/util.js' | |||
| export default{ | |||
| name:'UserAnalysis', | |||
| data() { | |||
| return { | |||
| type_val:'', | |||
| recordBeginTime:'', | |||
| lastUpdatedTime:'', | |||
| page:1, | |||
| pageSize:10, | |||
| params:{startDate:'',endDate:''}, | |||
| tableData: [], | |||
| totalNum:0, | |||
| dataUrl:'../../api/v1/query_user_metrics_page', | |||
| dataYesterdayUrl:'../../api/v1/query_metrics_yesterday', | |||
| ys_count:0, | |||
| tableDataYesterday: {}, | |||
| option:'', | |||
| optionYesterdayUser:'', | |||
| optionYesterdaAllUser:'', | |||
| echartsSelectData:'', | |||
| echartsYsAddUser:'', | |||
| echartsYsAllUser:'', | |||
| pickerOptions: { | |||
| }, | |||
| value_time: '', | |||
| search:'', | |||
| data:'', | |||
| // columns: [{title: 'ID',key: 'ID'},{title: '用户名',key: 'Name'},{title: 'PR数',key: 'CodeMergeCount'},{title: 'commit数',key:'CommitCount'},{title: '提出任务数',key: 'IssueCount'},{title: '评论数',key: 'CommentCount'},{title: '关注项目数',key: 'FocusRepoCount'},{title: '点赞项目数',key: 'StarRepoCount'},{title: '登录次数',key: 'LoginCount'},{title:'关注者数',key:'WatchedCount'},{title:'commit代码行数',key:'CommitCodeSize'},{title:'已解决任务数',key:'SolveIssueCount'},{title:'百科页面贡献次数',key:'EncyclopediasCount'},{title:'创建项目',key:'CreateRepoCount'},{title:'用户注册时间',key:'RegistDate'},{title:'云脑任务数',key:'CloudBrainTaskNum'},{title:'云脑运行时间(小时)',key:'CloudBrainRunTime'},{title:'上传(提交)数据集文件数',key:'CommitDatasetNum'},{title:'提交模型数',key:'CommitModelCount'},{title:'用户指数',key:'UserIndex'},{title:'系统统计时间',key:'CountDate'}], | |||
| blob:'', | |||
| fileName:'', | |||
| dynamic:4, | |||
| params_pro:{type:'all',page:1,pagesize:10,beginTime:'',endTime:'',q:'',sort:'openi'}, | |||
| }; | |||
| }, | |||
| methods: { | |||
| popMark(){ | |||
| alert("数据为空时,不能下载!") | |||
| }, | |||
| // exportData(){ | |||
| // // this.getUserList('all_usr',7) | |||
| // var saveFileName = this.getFileName() | |||
| // export2Excel(this.columns,this.tableData,saveFileName) | |||
| // }, | |||
| // getFileName(){ | |||
| // var saveFileName='' | |||
| // var Date=(this.params.startDate).split('-') | |||
| // var startDate=Date[0]+''+Date[1]+''+Date[2] | |||
| // Date=(this.params.endDate).split('-') | |||
| // var endDate=Date[0]+Date[1]+Date[2] | |||
| // saveFileName = '用户分析_'+this.search+''+startDate+'_'+endDate | |||
| // if (this.type_val=='all_usr'){ | |||
| // saveFileName = '用户分析_'+this.search+'_all' | |||
| // } | |||
| // return saveFileName | |||
| // }, | |||
| handleCurrentChange(val){ | |||
| this.page = val | |||
| }, | |||
| handleSizeChange(val){ | |||
| this.pageSize = val | |||
| }, | |||
| resetPage(){ | |||
| this.page=1 | |||
| }, | |||
| addUser(val1, val2){ | |||
| return (val1+val2) | |||
| }, | |||
| formatDate(myyear,mymonth,myweekday) { | |||
| // var myyear = this.date.getFullYear(); | |||
| // var mymonth = this.date.getMonth() + 1; | |||
| // var myweekday = this.date.getDate(); | |||
| if (mymonth < 10) { | |||
| mymonth = "0" + mymonth; | |||
| } | |||
| if (myweekday < 10) { | |||
| myweekday = "0" + myweekday; | |||
| } | |||
| return (myyear + "-" + mymonth + "-" + myweekday); | |||
| }, | |||
| // 获得某月的天数 | |||
| getMonthDays(nowYear,month){ | |||
| let monthStartDate = new Date(nowYear, month, 1); | |||
| let monthEndDate = new Date(nowYear, month + 1, 1); | |||
| let days = (monthEndDate - monthStartDate)/(1000 * 60 * 60 * 24); | |||
| return days; | |||
| }, | |||
| getUpdateTime(){ | |||
| this.$axios.get('../../api/v1/query_metrics_yesterday',{ | |||
| params:this.params_pro | |||
| }).then((res)=>{ | |||
| this.recordBeginTime=res.data.datarecordbegintime | |||
| this.lastUpdatedTime=res.data.lastUpdatedTime | |||
| }) | |||
| }, | |||
| getUserList(type_val,index){ | |||
| this.type_val = type_val | |||
| this.dynamic = index; | |||
| var now = new Date(); // 当前日期 | |||
| var nowDayOfWeek = now.getDay(); // 今天本周的第几天 | |||
| var nowDay = now.getDate(); // 当前日 | |||
| var nowMonth = now.getMonth(); // 当前月 | |||
| var nowYear = now.getFullYear(); // 当前年 | |||
| var today = this.formatDate(nowYear,nowMonth+1,nowDay); | |||
| let lastMonthDate = new Date(); // 上月日期 | |||
| lastMonthDate.setDate(1); | |||
| lastMonthDate.setMonth(lastMonthDate.getMonth()-1); | |||
| let lastYear = lastMonthDate.getYear(); | |||
| let lastMonth = lastMonthDate.getMonth(); | |||
| this.dataUrl = '../../api/v1/query_user_metrics_page'; | |||
| if (typeof type_val=="undefined" || type_val=="null" || type_val==""){ | |||
| this.params.startDate= this.formatDate(this.value_time[0].getFullYear(),this.value_time[0].getMonth() + 1,this.value_time[0].getDate()); | |||
| this.params.endDate = this.formatDate(this.value_time[1].getFullYear(),this.value_time[1].getMonth() + 1,this.value_time[1].getDate()); | |||
| }else{ | |||
| switch(type_val){ | |||
| case "yesterday_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_yesterday'; | |||
| break | |||
| } | |||
| case "current_week_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_current_week'; | |||
| break | |||
| } | |||
| case "current_month_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_current_month'; | |||
| break | |||
| } | |||
| case "last_month_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_last_month'; | |||
| break | |||
| } | |||
| case "monthly_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_last30_day'; | |||
| break | |||
| } | |||
| case "current_year_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_current_year'; | |||
| break | |||
| } | |||
| case "all_usr":{ | |||
| this.value_time=[] | |||
| this.dataUrl = '../../api/v1/query_metrics_all'; | |||
| break | |||
| } | |||
| } | |||
| }; | |||
| this.$axios.get(this.dataUrl,{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| this.tableData = res.data.data | |||
| // console.log("res.data:"+res.data.data) | |||
| this.totalNum = res.data.count | |||
| this.drawSelectData() | |||
| }) | |||
| }, | |||
| getYesterdayUser(){ | |||
| this.$axios.get(this.dataYesterdayUrl,{ | |||
| }).then((res)=>{ | |||
| this.ys_count = res.data.count | |||
| this.tableDataYesterday = res.data.data[0] | |||
| if(this.ys_count>0){ | |||
| this.drawYesterdayUser() | |||
| this.drawSumUser() | |||
| }else{ | |||
| document.getElementById("isShow").style.display='none' | |||
| } | |||
| }) | |||
| }, | |||
| drawYesterdayUser(){ | |||
| this.optionYesterdayUser = { | |||
| tooltip: { | |||
| trigger: 'item', | |||
| show:false | |||
| }, | |||
| legend: { | |||
| top: '5%', | |||
| left: 'center', | |||
| show:false | |||
| }, | |||
| // graphic:{ | |||
| // type:'text', | |||
| // left:'center', | |||
| // top:'center', | |||
| // style:{ | |||
| // text:this.tableDataYesterday.TotalRegistUser, | |||
| // fontSize:18, | |||
| // fontWeight:'bold', | |||
| // color:'#101010' | |||
| // } | |||
| // }, | |||
| color:['#5087Ec','#DBDBDB'], | |||
| series: [ | |||
| { | |||
| name: '', | |||
| type: 'pie', | |||
| radius: ['65%', '70%'], | |||
| center:['50%','50%'], | |||
| avoidLabelOverlap: false, | |||
| label: { | |||
| normal:{ | |||
| show: true, | |||
| position: 'center', | |||
| formatter:''+this.tableDataYesterday.TotalRegistUser, | |||
| fontSize:18, | |||
| fontWeight:'bold', | |||
| color:'#101010' | |||
| } | |||
| }, | |||
| emphasis: { | |||
| label: { | |||
| show: false, | |||
| fontSize: '40', | |||
| fontWeight: 'bold' | |||
| } | |||
| }, | |||
| labelLine: { | |||
| normal:{ | |||
| show:false | |||
| } | |||
| }, | |||
| data: [ | |||
| { value: this.tableDataYesterday.ActivateRegistUser, name: '已激活' }, | |||
| { value: this.tableDataYesterday.NotActivateRegistUser, name: '未激活'}, | |||
| ], | |||
| hoverAnimation:false, | |||
| } | |||
| ] | |||
| }; | |||
| this.echartsYsAddUser.setOption(this.optionYesterdayUser) | |||
| }, | |||
| drawSumUser(){ | |||
| this.optionYesterdaAllUser = { | |||
| tooltip: { | |||
| trigger: 'item', | |||
| show:false | |||
| }, | |||
| legend: { | |||
| top: '5%', | |||
| left: 'center', | |||
| show:false | |||
| }, | |||
| // graphic:{ | |||
| // type:'text', | |||
| // left:'center', | |||
| // top:'center', | |||
| // style:{ | |||
| // text:this.tableDataYesterday.TotalRegistUser, | |||
| // fontSize:18, | |||
| // fontWeight:'bold', | |||
| // color:'#101010' | |||
| // } | |||
| // }, | |||
| color:['#5087Ec','#DBDBDB'], | |||
| series: [ | |||
| { | |||
| name: '', | |||
| type: 'pie', | |||
| radius: ['65%', '70%'], | |||
| center:['50%','50%'], | |||
| avoidLabelOverlap: false, | |||
| label: { | |||
| normal:{ | |||
| show: true, | |||
| position: 'center', | |||
| formatter:''+this.tableDataYesterday.TotalUser, | |||
| fontSize:18, | |||
| fontWeight:'bold', | |||
| color:'#101010' | |||
| } | |||
| }, | |||
| emphasis: { | |||
| label: { | |||
| show: false, | |||
| fontSize: '40', | |||
| fontWeight: 'bold' | |||
| } | |||
| }, | |||
| labelLine: { | |||
| normal:{ | |||
| show:false | |||
| } | |||
| }, | |||
| data: [ | |||
| { value: this.tableDataYesterday.TotalActivateRegistUser, name: '已激活' }, | |||
| { value: this.tableDataYesterday.TotalNotActivateRegistUser, name: '未激活'}, | |||
| ], | |||
| hoverAnimation:false, | |||
| } | |||
| ] | |||
| }; | |||
| this.echartsYsAllUser.setOption(this.optionYesterdaAllUser) | |||
| }, | |||
| // searchName(){ | |||
| // this.params.userName = this.search | |||
| // this.params.page = 1 | |||
| // this.page=1 | |||
| // this.getUserList(this.type_val, this.dynamic) | |||
| // }, | |||
| tableHeaderStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex===0){ | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| cellStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex%2 === 1){ | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| drawSelectData(){ | |||
| // $("#selectData").removeAttr("selectData").empty(); | |||
| var xdata=[] | |||
| var ydata_TotalRegistUser=[] | |||
| var ydata_ActivateRegistUser=[] | |||
| var ydata_NotActivateRegistUser=[] | |||
| var ydata_RegistActivityUser=[] | |||
| var ydata_TotalUser=[] | |||
| var ydata_TotalActivateRegistUser=[] | |||
| var ydata_TotalHasActivityUser=[] | |||
| // if () | |||
| for(var i =0;i<this.tableData.length;i++){ | |||
| xdata.push(this.tableData[this.tableData.length-1-i].DisplayDate); | |||
| ydata_TotalRegistUser.push(this.tableData[this.tableData.length-1-i].TotalRegistUser) | |||
| ydata_ActivateRegistUser.push(this.tableData[this.tableData.length-1-i].ActivateRegistUser) | |||
| ydata_RegistActivityUser.push(this.tableData[this.tableData.length-1-i].HasActivityUser) | |||
| ydata_NotActivateRegistUser.push(this.tableData[this.tableData.length-1-i].NotActivateRegistUser) | |||
| ydata_TotalUser.push(this.tableData[this.tableData.length-1-i].TotalUser) | |||
| ydata_TotalActivateRegistUser.push(this.tableData[this.tableData.length-1-i].TotalActivateRegistUser) | |||
| ydata_TotalHasActivityUser.push(this.tableData[this.tableData.length-1-i].TotalHasActivityUser) | |||
| } | |||
| this.option = { | |||
| title : { | |||
| text: '', | |||
| textStyle: { | |||
| fontSize: 12, | |||
| }, | |||
| left:'center', | |||
| top:'bottom', | |||
| subtext: '', | |||
| }, | |||
| tooltip : { | |||
| trigger: 'axis', | |||
| backgroundColor:'rgba(255,255,255,0.8)', | |||
| color:'black', | |||
| borderWidth:'1', | |||
| borderColor:'gray', | |||
| textStyle:{ | |||
| color:'black' | |||
| }, | |||
| }, | |||
| legend: { | |||
| data:['新增注册用户','新增已激活','新增有贡献活动','新增未激活','累计注册用户','累计已激活','累计有贡献活动'], | |||
| selected:{ | |||
| // '新增注册用户':true, | |||
| // '新增已激活':true, | |||
| // '新增有贡献活动':true, | |||
| // '新增未激活':false, | |||
| // '累计注册用户':false, | |||
| // '累计已激活':false, | |||
| // '累计有贡献活动':false | |||
| } | |||
| // orient: 'vertical', | |||
| // top:'top', | |||
| }, | |||
| toolbox: { | |||
| show : false, | |||
| feature : { | |||
| mark : {show: true}, | |||
| dataView : {show: false, readOnly: false}, | |||
| magicType : {show: true, type: ['line', 'bar']}, | |||
| restore : {show: false}, | |||
| saveAsImage : {show: true} | |||
| } | |||
| }, | |||
| calculable : true, | |||
| xAxis : [ | |||
| { | |||
| type : 'category', | |||
| data : xdata, | |||
| axisLine: { | |||
| show: false, //x轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| yAxis : [ | |||
| { | |||
| type : 'value', | |||
| axisLine: { | |||
| show: false, //y轴线消失 | |||
| }, | |||
| axisTick:{ | |||
| show:false//刻度隐藏 | |||
| } | |||
| } | |||
| ], | |||
| series : [ | |||
| { name:"新增注册用户", | |||
| data: ydata_TotalRegistUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#3894FF ", | |||
| }, | |||
| color:"#3894FF ", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增已激活", | |||
| data: ydata_ActivateRegistUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#67B3BB", | |||
| }, | |||
| color:"#67B3BB", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增有贡献活动", | |||
| data: ydata_RegistActivityUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#58A55C", | |||
| }, | |||
| color:"#58A55C", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"新增未激活", | |||
| data: ydata_NotActivateRegistUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#F2BD42", | |||
| }, | |||
| color:"#F2BD42", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"累计注册用户", | |||
| data: ydata_TotalUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#2E4552", | |||
| }, | |||
| color:"#2E4552", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"累计已激活", | |||
| data: ydata_TotalActivateRegistUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#4786B4", | |||
| }, | |||
| color:"#4786B4", | |||
| } | |||
| }, | |||
| }, | |||
| { | |||
| name:"累计有贡献活动", | |||
| data: ydata_TotalHasActivityUser, | |||
| type: 'line', | |||
| areaStyle: {}, | |||
| itemStyle:{ | |||
| normal:{ | |||
| lineStyle:{ | |||
| color:"#4E9C8F", | |||
| }, | |||
| color:"#4E9C8F", | |||
| } | |||
| }, | |||
| }, | |||
| ] | |||
| }; | |||
| // this.echartsSelectData.resize() | |||
| var checkboxs=document.getElementsByName('checkboxchart'); | |||
| // $(".checkboxchart").click(function(){ | |||
| for(var i=0; i<checkboxs.length; i++){ | |||
| // console.log("selectArr[i]:",this.option.legend.data[i]) | |||
| if(checkboxs[i].checked){ | |||
| this.option.legend.selected[this.option.legend.data[i]]=true; | |||
| }else{ | |||
| this.option.legend.selected[this.option.legend.data[i]]=false; | |||
| } | |||
| } | |||
| this.echartsSelectData.setOption(this.option) | |||
| // this.clickCheckBox() | |||
| // setTimeout(function (){ | |||
| // window.onresize = function () { | |||
| // this.echartsSelectData.resize; | |||
| // } | |||
| // },200) | |||
| // // 使用刚指定的选择项数据显示图表。 | |||
| // var selectArr = this.echartsSelectData.getOption().legend[0].data;//legend所有值 | |||
| // var checkboxs=document.getElementsByName('checkboxchart'); | |||
| // $(".checkboxchart").click(function(){ | |||
| // var obj = {}; | |||
| // for(var i=0; i<checkboxs.length; i++){ | |||
| // if(checkboxs[i].checked){ | |||
| // obj[selectArr[i]] = true; | |||
| // }else{ | |||
| // obj[selectArr[i]] = false; | |||
| // } | |||
| // } | |||
| // option.legend.selected = obj; | |||
| // this.echartsSelectData.setOption(option); | |||
| // }); | |||
| }, | |||
| clickCheckBox(){ | |||
| // 使用刚指定的选择项数据显示图表。 | |||
| var selectArr = this.echartsSelectData.getOption().legend[0].data;//legend所有值 | |||
| var checkboxs=document.getElementsByName('checkboxchart'); | |||
| // $(".checkboxchart").click(function(){ | |||
| var obj = {}; | |||
| for(var i=0; i<checkboxs.length; i++){ | |||
| if(checkboxs[i].checked){ | |||
| obj[selectArr[i]] = true; | |||
| }else{ | |||
| obj[selectArr[i]] = false; | |||
| } | |||
| } | |||
| // console.log("obj:",obj) | |||
| this.option.legend.selected = obj; | |||
| this.echartsSelectData.setOption(this.option); | |||
| // }); | |||
| }, | |||
| }, | |||
| filters:{ | |||
| rounding (value) { | |||
| if(value>=1){ | |||
| return "100%" | |||
| }else if(value==0){ | |||
| return "-" | |||
| }else{ | |||
| return Number(value*100).toFixed(2) + "%" | |||
| } | |||
| }, | |||
| transformTimestamp(timestamp){ | |||
| let a = new Date(timestamp*1000); | |||
| const date = new Date(a); | |||
| const Y = date.getFullYear() + '/'; | |||
| const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '/'; | |||
| const D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' '; | |||
| const h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':'; | |||
| const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes());// + ':' ; | |||
| // const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒 | |||
| const dateString = Y + M + D + h + m ;//+ s; | |||
| return dateString; | |||
| }, | |||
| addUser(val1,val2){ | |||
| return val1+val2 | |||
| } | |||
| }, | |||
| mounted() { | |||
| // document.getElementById("all_usr").style.outline="none" | |||
| // document.getElementById("all_usr").focus() | |||
| this.getUpdateTime() | |||
| this.getUserList("monthly_usr",4) | |||
| this.getYesterdayUser() | |||
| document.getElementById('selectData').style.width = document.getElementById('user_tend').offsetWidth*0.8+'px' | |||
| this.echartsSelectData = this.$echarts.init(document.getElementById('selectData')) | |||
| this.echartsYsAddUser = this.$echarts.init(document.getElementById('ys_add_user')) | |||
| this.echartsYsAllUser = this.$echarts.init(document.getElementById('ys_all_user')) | |||
| }, | |||
| created() { | |||
| this.getUserList("monthly_usr",4) | |||
| this.getYesterdayUser() | |||
| }, | |||
| watch:{ | |||
| // search(val){ | |||
| // if(!val){ | |||
| // this.params.userName = this.search | |||
| // this.params.page = 1 | |||
| // this.page=1 | |||
| // this.getUserList(this.type_val, this.dynamic) | |||
| // } | |||
| // } | |||
| }, | |||
| } | |||
| </script> | |||
| <style scoped> | |||
| .pro_item{ | |||
| font-size: 16px; | |||
| color: rgba(16, 16, 16, 100); | |||
| font-family: SourceHanSansSC-bold; | |||
| } | |||
| .sta_item{ | |||
| font-size: 14px; | |||
| color: rgb(0 0 0); | |||
| font-family: SourceHanSansSC-bold; | |||
| } | |||
| .update_time{ | |||
| line-height: 17px; | |||
| font-size: 12px; | |||
| color:rgba(187, 187, 187, 100); | |||
| margin-left: 10px; | |||
| } | |||
| /* .btn{ | |||
| line-height: 1.5; | |||
| margin: -3px; | |||
| border: 1px solid #409effd6; | |||
| background: #FFFF; | |||
| color: #409eff; | |||
| width: 60px; | |||
| height: 30px; | |||
| border-radius:4px ; | |||
| } */ | |||
| .btnFirst{ | |||
| line-height: 1.5; | |||
| margin: -3.5px; | |||
| border: 1px solid rgba(22, 132, 252, 100); | |||
| border-right: none; | |||
| background: #FFFF; | |||
| color: #1684FC; | |||
| width: 60px; | |||
| height: 30px; | |||
| border-radius:4px 0px 0px 4px; | |||
| } | |||
| .btn{ | |||
| line-height: 1.5; | |||
| margin: -3.5px; | |||
| border: 1px solid rgba(22, 132, 252, 100); | |||
| border-right: none; | |||
| background: #FFFF; | |||
| color: #1684FC; | |||
| width: 60px; | |||
| height: 30px; | |||
| } | |||
| .btnLast{ | |||
| line-height: 1.5; | |||
| margin: -3.5px; | |||
| border: 1px solid rgba(22, 132, 252, 100); | |||
| /* border-right: none; */ | |||
| background: #FFFF; | |||
| color: #1684FC; | |||
| width: 60px; | |||
| height: 30px; | |||
| border-radius:0px 4px 4px 0px; | |||
| } | |||
| .btnFirst,.btn,.btnLast { | |||
| cursor: pointer; | |||
| } | |||
| /* .btn:focus, | |||
| .btn:active{ | |||
| background-color:#409effd6 ; | |||
| } */ | |||
| /* /deep/ .el-date-picker { | |||
| width: 220px; | |||
| } */ | |||
| /deep/ .el-table { | |||
| font-size: 12px; | |||
| } | |||
| /deep/ .el-table tbody tr:hover>td { | |||
| background-color:#D3D3D3!important; | |||
| opacity:1 | |||
| } | |||
| /deep/ .el-range-separator{ | |||
| width: 20% !important; | |||
| } | |||
| /deep/ .el-pagination { | |||
| padding-bottom: 30px; | |||
| } | |||
| .colorChange { | |||
| background-color: #1684FC; | |||
| color: #FFFF; | |||
| cursor: default; | |||
| } | |||
| .item_echart{ | |||
| margin-top: 10px; | |||
| margin-right: 5px; | |||
| border:1px solid rgba(219, 219, 219, 100); | |||
| height: 350px; | |||
| width: 100%; | |||
| } | |||
| .yesterday_blk{ | |||
| display: block; | |||
| margin-top:40px | |||
| } | |||
| .yesterday_pdrt{ | |||
| padding-left: 10px; | |||
| } | |||
| .yesterday_color1{ | |||
| border-left: 3px solid #DBDBDB; | |||
| } | |||
| .yesterday_color2{ | |||
| border-left: 3px solid #5087Ec; | |||
| } | |||
| .yesterday_title{ | |||
| font-size: 14px; | |||
| font-weight: bold; | |||
| } | |||
| .yesterday_text{ | |||
| font-size: 12px; | |||
| line-height: 12px; | |||
| color: #888888; | |||
| margin-top: 10px; | |||
| } | |||
| .bold_num{ | |||
| font-weight: bold; | |||
| } | |||
| .draw_region{ | |||
| width: 180px; | |||
| height: 180px; | |||
| } | |||
| </style> | |||
| @@ -77,9 +77,11 @@ | |||
| align="center" | |||
| > | |||
| <template slot-scope="scope"> | |||
| <a :href="'/' + scope.row.userName" :title="scope.row.userName"> | |||
| <a v-if="scope.row.userName||scope.row.relAvatarLink" :href="'/' + scope.row.userName" :title="scope.row.userName"> | |||
| <img :src="scope.row.relAvatarLink" class="ui avatar image"> | |||
| </a> | |||
| <a v-else><img class="ui avatar image" title="Ghost" src="/user/avatar/ghost/-1"></a> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| @@ -368,9 +370,10 @@ | |||
| align="center" | |||
| > | |||
| <template slot-scope="scope"> | |||
| <a :href="'/' + scope.row.userName" :title="scope.row.userName"> | |||
| <a v-if="scope.row.userName||scope.row.relAvatarLink" :href="'/' + scope.row.userName" :title="scope.row.userName"> | |||
| <img :src="scope.row.relAvatarLink" class="ui avatar image"> | |||
| </a> | |||
| <a v-else><img class="ui avatar image" title="Ghost" src="/user/avatar/ghost/-1"></a> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| @@ -638,6 +641,15 @@ export default { | |||
| cInput.select() | |||
| document.execCommand('Copy') | |||
| cInput.remove() | |||
| $('body') | |||
| .toast({ | |||
| message: '复制成功!', | |||
| showProgress: 'bottom', | |||
| showIcon:'check circle', | |||
| class: 'info', | |||
| position: 'top right', | |||
| }) | |||
| ; | |||
| }, | |||
| searchName(){ | |||
| if(this.activeName=='first'){ | |||
| @@ -1,395 +1,387 @@ | |||
| <template> | |||
| <div > | |||
| <div class="ui container" style="width: 80%;"> | |||
| <div class="ui grid"> | |||
| <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||
| <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" @keyup.enter="searchName()"> | |||
| <button class="ui blue button" @click="searchName()">搜索</button> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <div class="ui container" style="width: 80%;"> | |||
| <div class="ui grid"> | |||
| <div class="row" style="border: 1px solid #d4d4d5;margin-top: 15px;padding-top: 0;"> | |||
| <div class="ui ten wide column" style="margin: 1rem 0;"> | |||
| <el-checkbox v-model="checked" style="padding: 0.5rem 1rem;">仅显示平台推荐</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-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> | |||
| </div> | |||
| <div class="ui sixteen wide column" style="padding: 0;"> | |||
| <el-table | |||
| :data="tableDataCustom" | |||
| style="width: 100%" | |||
| :header-cell-style="tableHeaderStyle" | |||
| > | |||
| <el-table-column | |||
| label="镜像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> | |||
| <i class="ri-lock-2-line" style="color: #fa8c16;padding: 0 1rem;" v-if="scope.row.isPrivate"></i> | |||
| <img v-if="scope.row.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;"> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| label="镜像描述" | |||
| min-width="28%" | |||
| align="left" | |||
| prop="description" | |||
| > | |||
| <template slot-scope="scope"> | |||
| <div class="image_desc" :title="scope.row.description">{{ scope.row.description}}</div> | |||
| <div v-if="!!scope.row.topics"> | |||
| <span v-for="(topic,index) in scope.row.topics" class="ui repo-topic label topic" style="cursor: default;">{{topic}}</span> | |||
| <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" | |||
| @keyup.enter="searchName()"> | |||
| <button class="ui blue button" @click="searchName()">搜索</button> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="cloudbrainType" | |||
| label="可用集群" | |||
| 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" | |||
| > | |||
| <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> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="creator" | |||
| label="创建者" | |||
| min-width="7%" | |||
| align="center" | |||
| > | |||
| <template slot-scope="scope"> | |||
| <a :href="'/' + scope.row.userName" :title="scope.row.userName"> | |||
| <img :src="scope.row.relAvatarLink" class="ui avatar image"> | |||
| </a> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| prop="createdUnix" | |||
| label="创建时间" | |||
| align="center" | |||
| min-width="13%" | |||
| > | |||
| <template slot-scope="scope"> | |||
| {{scope.row.createdUnix | transformTimestamp}} | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column | |||
| align="center" | |||
| min-width="23%" | |||
| label="操作" | |||
| > | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex;justify-content: flex-end;align-items: center;"> | |||
| <div style="display: flex;align-items: center;cursor: default;;padding: 0 1rem;"> | |||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke"><path d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"></path></svg> | |||
| <span style="line-height: 2;margin-left:0.3rem;">{{scope.row.numStars}}</span> | |||
| </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-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-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> | |||
| </div> | |||
| <div class="ui sixteen wide column" style="padding: 0;"> | |||
| <el-table :data="tableDataCustom" style="width: 100%" :header-cell-style="tableHeaderStyle"> | |||
| <el-table-column label="镜像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> | |||
| <i class="ri-lock-2-line" style="color: #fa8c16;padding: 0 1rem;" | |||
| v-if="scope.row.isPrivate"></i> | |||
| <img v-if="scope.row.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;"> | |||
| </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> | |||
| <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> | |||
| <span style="padding: 0 1rem;color:#0366d6;cursor:pointer;" @click="copyUrl(scope.row.place)">复制地址</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> | |||
| </span> | |||
| <el-dropdown-menu slot="dropdown"> | |||
| <el-dropdown-item @click.native="eidtImage(scope.row.id)">编辑</el-dropdown-item> | |||
| <el-dropdown-item style="color: red;" @click.native="deleteImage(scope.row.id)">删除</el-dropdown-item> | |||
| </el-dropdown-menu> | |||
| </el-dropdown> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column label="镜像描述" min-width="28%" align="left" prop="description"> | |||
| <template slot-scope="scope"> | |||
| <div class="image_desc" :title="scope.row.description">{{ scope.row.description}} | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| </el-table> | |||
| </div> | |||
| <div class="ui container" style="padding:2rem 0;text-align:center"> | |||
| <el-pagination | |||
| background | |||
| @size-change="handleSizeChangeCustom" | |||
| @current-change="handleCurrentChangeCustom" | |||
| :current-page="currentPageCustom" | |||
| :page-size="pageSizeCustom" | |||
| :page-sizes="[5,15,20]" | |||
| layout="total, sizes, prev, pager, next, jumper" | |||
| :total="totalNumCustom"> | |||
| </el-pagination> | |||
| <div v-if="!!scope.row.topics"> | |||
| <span v-for="(topic,index) in scope.row.topics" | |||
| class="ui repo-topic label topic" style="cursor: default;">{{topic}}</span> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column prop="cloudbrainType" label="可用集群" 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"> | |||
| <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> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column prop="creator" label="创建者" 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"> | |||
| <img :src="scope.row.relAvatarLink" class="ui avatar image"> | |||
| </a> | |||
| <a v-else> | |||
| <img class="ui avatar image" title="Ghost" src="/user/avatar/ghost/-1"> | |||
| </a> | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column prop="createdUnix" label="创建时间" align="center" min-width="13%"> | |||
| <template slot-scope="scope"> | |||
| {{scope.row.createdUnix | transformTimestamp}} | |||
| </template> | |||
| </el-table-column> | |||
| <el-table-column align="center" min-width="23%" label="操作"> | |||
| <template slot-scope="scope"> | |||
| <div style="display: flex;justify-content: flex-end;align-items: center;"> | |||
| <div | |||
| style="display: flex;align-items: center;cursor: default;;padding: 0 1rem;"> | |||
| <svg width="1.4em" height="1.4em" viewBox="0 0 32 32" class="heart-stroke"> | |||
| <path | |||
| d="M4.4 6.54c-1.761 1.643-2.6 3.793-2.36 6.056.24 2.263 1.507 4.521 3.663 6.534a29110.9 29110.9 0 0010.296 9.633l10.297-9.633c2.157-2.013 3.424-4.273 3.664-6.536.24-2.264-.599-4.412-2.36-6.056-1.73-1.613-3.84-2.29-6.097-1.955-1.689.25-3.454 1.078-5.105 2.394l-.4.319-.398-.319c-1.649-1.316-3.414-2.143-5.105-2.394a7.612 7.612 0 00-1.113-.081c-1.838 0-3.541.694-4.983 2.038z"> | |||
| </path> | |||
| </svg> | |||
| <span | |||
| style="line-height: 2;margin-left:0.3rem;">{{scope.row.numStars}}</span> | |||
| </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> | |||
| <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> | |||
| <span style="padding: 0 1rem;color:#0366d6;cursor:pointer;" | |||
| @click="copyUrl(scope.row.place)">复制地址</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> | |||
| </span> | |||
| <el-dropdown-menu slot="dropdown"> | |||
| <el-dropdown-item @click.native="eidtImage(scope.row.id)">编辑 | |||
| </el-dropdown-item> | |||
| <el-dropdown-item style="color: red;" | |||
| @click.native="deleteImage(scope.row.id)">删除</el-dropdown-item> | |||
| </el-dropdown-menu> | |||
| </el-dropdown> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| </el-table-column> | |||
| </el-table> | |||
| </div> | |||
| <div class="ui container" style="padding:2rem 0;text-align:center"> | |||
| <el-pagination background @size-change="handleSizeChangeCustom" | |||
| @current-change="handleCurrentChangeCustom" :current-page="currentPageCustom" | |||
| :page-size="pageSizeCustom" :page-sizes="[5,15,20]" | |||
| layout="total, sizes, prev, pager, next, jumper" :total="totalNumCustom"> | |||
| </el-pagination> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config; | |||
| const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config; | |||
| export default { | |||
| components: { | |||
| }, | |||
| data() { | |||
| return { | |||
| search:'', | |||
| dropdownPrivate:'全部', | |||
| checked:false, | |||
| currentPageCustom:1, | |||
| pageSizeCustom:15, | |||
| totalNumCustom:0, | |||
| paramsCustom:{page:1,pageSize:15,q:'',recommend:false}, | |||
| tableDataCustom: [], | |||
| starCustom:[], | |||
| loadingCustom:false, | |||
| }; | |||
| }, | |||
| methods: { | |||
| tableHeaderStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex===0){ | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| handleSizeChangeCustom(val){ | |||
| this.paramsCustom.pageSize = val | |||
| this.getImageListCustom() | |||
| }, | |||
| handleCurrentChangeCustom(val){ | |||
| this.paramsCustom.page = val | |||
| this.getImageListCustom() | |||
| }, | |||
| getImageListCustom(){ | |||
| this.loadingCustom = true | |||
| this.$axios.get('/admin/images/data',{ | |||
| params:this.paramsCustom | |||
| }).then((res)=>{ | |||
| this.totalNumCustom = res.data.count | |||
| this.tableDataCustom = res.data.images | |||
| this.tableDataCustom.forEach(element => { | |||
| this.starCustom.push({id:element.id,}) | |||
| }); | |||
| this.loadingCustom = false | |||
| }) | |||
| }, | |||
| deleteImage(id){ | |||
| let flag=1 | |||
| let _this = this | |||
| $('.ui.basic.modal.images') | |||
| .modal({ | |||
| onDeny: function() { | |||
| flag = false | |||
| export default { | |||
| components: { | |||
| }, | |||
| data() { | |||
| return { | |||
| search: '', | |||
| dropdownPrivate: '全部', | |||
| checked: false, | |||
| currentPageCustom: 1, | |||
| pageSizeCustom: 15, | |||
| totalNumCustom: 0, | |||
| paramsCustom: { page: 1, pageSize: 15, q: '', recommend: false }, | |||
| tableDataCustom: [], | |||
| starCustom: [], | |||
| loadingCustom: false, | |||
| }; | |||
| }, | |||
| methods: { | |||
| tableHeaderStyle({ row, column, rowIndex, columnIndex }) { | |||
| if (rowIndex === 0) { | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| handleSizeChangeCustom(val) { | |||
| this.paramsCustom.pageSize = val | |||
| this.getImageListCustom() | |||
| }, | |||
| onApprove: function() { | |||
| _this.$axios.delete('/image/'+id).then((res)=>{ | |||
| _this.getImageListCustom() | |||
| handleCurrentChangeCustom(val) { | |||
| this.paramsCustom.page = val | |||
| this.getImageListCustom() | |||
| }, | |||
| getImageListCustom() { | |||
| this.loadingCustom = true | |||
| this.$axios.get('/admin/images/data', { | |||
| params: this.paramsCustom | |||
| }).then((res) => { | |||
| this.totalNumCustom = res.data.count | |||
| this.tableDataCustom = res.data.images | |||
| this.tableDataCustom.forEach(element => { | |||
| this.starCustom.push({ id: element.id, }) | |||
| }); | |||
| this.loadingCustom = false | |||
| }) | |||
| flag = true | |||
| }, | |||
| onHidden: function() { | |||
| if (flag == false) { | |||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||
| }else{ | |||
| $('.alert').html('删除成功').removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut(); | |||
| deleteImage(id) { | |||
| let flag = 1 | |||
| let _this = this | |||
| $('.ui.basic.modal.images') | |||
| .modal({ | |||
| onDeny: function () { | |||
| flag = false | |||
| }, | |||
| onApprove: function () { | |||
| _this.$axios.delete('/image/' + id).then((res) => { | |||
| _this.getImageListCustom() | |||
| }) | |||
| flag = true | |||
| }, | |||
| onHidden: function () { | |||
| if (flag == false) { | |||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||
| } else { | |||
| $('.alert').html('删除成功').removeClass('alert-danger').addClass('alert-success').show().delay(1500).fadeOut(); | |||
| } | |||
| } | |||
| }) | |||
| .modal('show') | |||
| }, | |||
| eidtImage(id) { | |||
| location.href = `/image/${id}/imageAdmin` | |||
| }, | |||
| imageStar(index, id, isStar) { | |||
| if (isStar) { | |||
| this.$axios.put(`/image/${id}/action/unstar`).then((res) => { | |||
| this.tableDataPublic[index].numStars = this.tableDataPublic[index].numStars - 1 | |||
| this.tableDataPublic[index].isStar = false | |||
| }) | |||
| } else { | |||
| this.$axios.put(`/image/${id}/action/star`).then((res) => { | |||
| this.tableDataPublic[index].numStars = this.tableDataPublic[index].numStars + 1 | |||
| this.tableDataPublic[index].isStar = true | |||
| }) | |||
| } | |||
| } | |||
| }) | |||
| .modal('show') | |||
| }, | |||
| eidtImage(id){ | |||
| location.href = `/image/${id}/imageAdmin` | |||
| }, | |||
| imageStar(index,id,isStar){ | |||
| if(isStar){ | |||
| this.$axios.put(`/image/${id}/action/unstar`).then((res)=>{ | |||
| this.tableDataPublic[index].numStars = this.tableDataPublic[index].numStars - 1 | |||
| this.tableDataPublic[index].isStar = false | |||
| }) | |||
| }else{ | |||
| this.$axios.put(`/image/${id}/action/star`).then((res)=>{ | |||
| this.tableDataPublic[index].numStars = this.tableDataPublic[index].numStars + 1 | |||
| this.tableDataPublic[index].isStar = true | |||
| }) | |||
| } | |||
| }, | |||
| copyUrl(url){ | |||
| const cInput = document.createElement('input') | |||
| cInput.value = url | |||
| document.body.appendChild(cInput) | |||
| cInput.select() | |||
| document.execCommand('Copy') | |||
| cInput.remove() | |||
| }, | |||
| searchName(){ | |||
| this.paramsCustom.q = this.search | |||
| this.paramsCustom.page = 1 | |||
| this.getImageListCustom() | |||
| }, | |||
| setRecommend(index,id){ | |||
| this.$axios.put(`/admin/image/${id}/action/recommend`).then((res)=>{ | |||
| this.tableDataCustom[index].type = 5 | |||
| }) | |||
| }, | |||
| unSetRecommend(index,id){ | |||
| this.$axios.put(`/admin/image/${id}/action/unrecommend`).then((res)=>{ | |||
| this.tableDataCustom[index].type = 0 | |||
| }) | |||
| }, | |||
| handleCommand(command){ | |||
| this.dropdownPrivate = command.label | |||
| this.paramsCustom.private = command.private | |||
| this.getImageListCustom() | |||
| } | |||
| }, | |||
| filters:{ | |||
| transformType(val){ | |||
| if(val==0){ | |||
| return "GPU" | |||
| } | |||
| }, | |||
| transformPravite(val){ | |||
| if(val){ | |||
| return "私有" | |||
| }else{ | |||
| return "公开" | |||
| } | |||
| }, | |||
| transformTimestamp(timestamp){ | |||
| }, | |||
| copyUrl(url) { | |||
| const cInput = document.createElement('input') | |||
| cInput.value = url | |||
| document.body.appendChild(cInput) | |||
| cInput.select() | |||
| document.execCommand('Copy') | |||
| cInput.remove() | |||
| }, | |||
| searchName() { | |||
| this.paramsCustom.q = this.search | |||
| this.paramsCustom.page = 1 | |||
| this.getImageListCustom() | |||
| }, | |||
| setRecommend(index, id) { | |||
| this.$axios.put(`/admin/image/${id}/action/recommend`).then((res) => { | |||
| this.tableDataCustom[index].type = 5 | |||
| }) | |||
| }, | |||
| unSetRecommend(index, id) { | |||
| this.$axios.put(`/admin/image/${id}/action/unrecommend`).then((res) => { | |||
| this.tableDataCustom[index].type = 0 | |||
| }) | |||
| }, | |||
| handleCommand(command) { | |||
| this.dropdownPrivate = command.label | |||
| this.paramsCustom.private = command.private | |||
| this.getImageListCustom() | |||
| } | |||
| }, | |||
| filters: { | |||
| transformType(val) { | |||
| if (val == 0) { | |||
| return "GPU" | |||
| } | |||
| }, | |||
| transformPravite(val) { | |||
| if (val) { | |||
| return "私有" | |||
| } else { | |||
| return "公开" | |||
| } | |||
| }, | |||
| transformTimestamp(timestamp) { | |||
| const date = new Date(parseInt(timestamp) * 1000); | |||
| const Y = date.getFullYear() + '-'; | |||
| const M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-'; | |||
| const D = (date.getDate() < 10 ? '0'+date.getDate() : date.getDate()) + ' '; | |||
| const h = (date.getHours() < 10 ? '0'+date.getHours() : date.getHours()) + ':'; | |||
| const m = (date.getMinutes() <10 ? '0'+date.getMinutes() : date.getMinutes()) + ':' ; | |||
| const s = (date.getSeconds() <10 ? '0'+date.getSeconds() : date.getSeconds()) ; // 秒 | |||
| const D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' '; | |||
| const h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':'; | |||
| const m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':'; | |||
| const s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()); // 秒 | |||
| const dateString = Y + M + D + h + m + s; | |||
| return dateString; | |||
| }, | |||
| }, | |||
| watch:{ | |||
| checked(val){ | |||
| this.paramsCustom.page = 1 | |||
| this.paramsCustom.recommend = val | |||
| this.getImageListCustom() | |||
| } | |||
| }, | |||
| watch: { | |||
| checked(val) { | |||
| this.paramsCustom.page = 1 | |||
| this.paramsCustom.recommend = val | |||
| this.getImageListCustom() | |||
| } | |||
| }, | |||
| mounted() { | |||
| this.getImageListCustom() | |||
| }, | |||
| created() { | |||
| } | |||
| }, | |||
| mounted() { | |||
| this.getImageListCustom() | |||
| }, | |||
| created() { | |||
| }; | |||
| } | |||
| }; | |||
| </script> | |||
| <style scoped> | |||
| .header-wrapper { | |||
| background-color: #f5f5f6; | |||
| padding-top: 15px; | |||
| } | |||
| .image_text{ | |||
| padding:25px 0 55px 0 ; | |||
| } | |||
| #header{ | |||
| position: relative; | |||
| top:-40px; | |||
| } | |||
| .el-dropdown-menu__item--divided{ | |||
| border-top: 1px solid blue; | |||
| } | |||
| .el-table thead{ | |||
| background-color: #f5f5f6; | |||
| } | |||
| /deep/ .el-tabs__item:hover{ | |||
| color: #000; | |||
| font-weight: 500; | |||
| } | |||
| /deep/ .el-tabs__item.is-active { | |||
| color: #000; | |||
| font-weight: 500; | |||
| } | |||
| /deep/ .el-tabs__active-bar{ | |||
| background-color:#000 | |||
| } | |||
| #success{ | |||
| background-color: #5bb973; | |||
| color: white; | |||
| } | |||
| .text-over{ | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| vertical-align: middle; | |||
| white-space: nowrap; | |||
| } | |||
| .image_title{ | |||
| display: inline-block; | |||
| cursor: default; | |||
| color: rgb(66, 98, 144); | |||
| } | |||
| .image_desc{ | |||
| -webkit-line-clamp: 2; | |||
| -webkit-box-orient: vertical; | |||
| display: -webkit-box; | |||
| text-overflow: ellipsis; | |||
| overflow: hidden; | |||
| } | |||
| .heart-stroke{ | |||
| stroke: #FA8C16; | |||
| stroke-width: 2; | |||
| fill: #fff | |||
| } | |||
| .stars_active{ | |||
| fill: #FA8C16 !important; | |||
| stroke:#FA8C16 !important | |||
| } | |||
| .header-new-drop{ | |||
| width: 100%; | |||
| } | |||
| </style> | |||
| .header-wrapper { | |||
| background-color: #f5f5f6; | |||
| padding-top: 15px; | |||
| } | |||
| .image_text { | |||
| padding: 25px 0 55px 0; | |||
| } | |||
| #header { | |||
| position: relative; | |||
| top: -40px; | |||
| } | |||
| .el-dropdown-menu__item--divided { | |||
| border-top: 1px solid blue; | |||
| } | |||
| .el-table thead { | |||
| background-color: #f5f5f6; | |||
| } | |||
| /deep/ .el-tabs__item:hover { | |||
| color: #000; | |||
| font-weight: 500; | |||
| } | |||
| /deep/ .el-tabs__item.is-active { | |||
| color: #000; | |||
| font-weight: 500; | |||
| } | |||
| /deep/ .el-tabs__active-bar { | |||
| background-color: #000 | |||
| } | |||
| #success { | |||
| background-color: #5bb973; | |||
| color: white; | |||
| } | |||
| .text-over { | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| vertical-align: middle; | |||
| white-space: nowrap; | |||
| } | |||
| .image_title { | |||
| display: inline-block; | |||
| cursor: default; | |||
| color: rgb(66, 98, 144); | |||
| } | |||
| .image_desc { | |||
| -webkit-line-clamp: 2; | |||
| -webkit-box-orient: vertical; | |||
| display: -webkit-box; | |||
| text-overflow: ellipsis; | |||
| overflow: hidden; | |||
| } | |||
| .heart-stroke { | |||
| stroke: #FA8C16; | |||
| stroke-width: 2; | |||
| fill: #fff | |||
| } | |||
| .stars_active { | |||
| fill: #FA8C16 !important; | |||
| stroke: #FA8C16 !important | |||
| } | |||
| .header-new-drop { | |||
| width: 100%; | |||
| } | |||
| </style> | |||
| @@ -1,76 +1,87 @@ | |||
| <template> | |||
| <div class="inline required field" :class="{ 'unite': benchmarkNew, 'min_title': benchmarkNew}"> | |||
| <label v-if="benchmarkNew" style="font-weight: normal;">镜像</label> | |||
| <label v-else>镜像</label> | |||
| <span v-if="benchmarkNew"> </span> | |||
| <input v-if="benchmarkNew" type="text" name="image" :value="imageAddress" style="width: 48.5%;" placeholder="选择镜像或输入镜像地址"> | |||
| <input v-else type="text" name="image" :value="imageAddress" placeholder="选择镜像或输入镜像地址"> | |||
| <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;">选择镜像</el-button> | |||
| <el-dialog | |||
| title="选择镜像" | |||
| :visible.sync="dialogVisible" | |||
| width="50%" | |||
| > | |||
| <div class="ui icon input" style="z-index: 9999;position: absolute;right: 50px;height:30px;"> | |||
| <i class="search icon" style="cursor: pointer;pointer-events:auto"></i> | |||
| <input type="text" placeholder="搜镜像Tag/描述/标签..." v-model="search"> | |||
| </div> | |||
| <el-tabs v-model="activeName" @tab-click="handleClick"> | |||
| <div class="inline required field" :class="{ 'unite': benchmarkNew, 'min_title': benchmarkNew}"> | |||
| <label v-if="benchmarkNew" style="font-weight: normal;">镜像</label> | |||
| <label v-else>镜像</label> | |||
| <span v-if="benchmarkNew"> </span> | |||
| <input v-if="benchmarkNew" type="text" name="image" :value="imageAddress" style="width: 48.5%;" | |||
| placeholder="选择镜像或输入镜像地址"> | |||
| <input v-else type="text" name="image" :value="imageAddress" placeholder="选择镜像或输入镜像地址"> | |||
| <el-button type="text" @click="dialogVisible = true" icon="el-icon-plus" style="color: #0366d6;">选择镜像 | |||
| </el-button> | |||
| <el-dialog title="选择镜像" :visible.sync="dialogVisible" width="50%"> | |||
| <div class="ui icon input" style="z-index: 9999;position: absolute;right: 50px;height:30px;"> | |||
| <i class="search icon" style="cursor: pointer;pointer-events:auto"></i> | |||
| <input type="text" placeholder="搜镜像Tag/描述/标签..." v-model="search"> | |||
| </div> | |||
| <el-tabs v-model="activeName" @tab-click="handleClick"> | |||
| <el-tab-pane label="公开镜像" name="first" v-loading="loadingPublic"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(publicData,index) in tableDataPublic" :key="index"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" | |||
| v-for="(publicData,index) in tableDataPublic" :key="index"> | |||
| <div style="width: 90%;"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;"> | |||
| <div style="display: flex;align-items: center;"> | |||
| <span class="panel_dataset_name text-over" style="margin-left: 0;">{{publicData.tag}} </span> | |||
| <img v-if="publicData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;"> | |||
| <span class="panel_dataset_name text-over" | |||
| style="margin-left: 0;">{{publicData.tag}} </span> | |||
| <img v-if="publicData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;"> | |||
| </div> | |||
| <div v-if="!!publicData.topics" class="text-over"> | |||
| <span v-for="(topic,index) in publicData.topics" class="ui repo-topic label topic">{{topic}}</span> | |||
| <span v-for="(topic,index) in publicData.topics" | |||
| class="ui repo-topic label topic">{{topic}}</span> | |||
| </div> | |||
| </div> | |||
| <div style="margin-top: 8px;display: flex;"> | |||
| <a :title="publicData.userName" style="cursor: default;"> | |||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="publicData.relAvatarLink"> | |||
| <a v-if="publicData.relAvatarLink||publicData.userName" :title="publicData.userName" | |||
| style="cursor: default;"> | |||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" | |||
| :src="publicData.relAvatarLink"> | |||
| </a> | |||
| <a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1" | |||
| style="width: 20px;height: 20px;"></a> | |||
| <span class="panel_datset_desc">{{publicData.description}}</span> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectImages(publicData.place,publicData.tag)">使用</button> | |||
| <button class="ui primary basic button mini" | |||
| @click.stop.prevent="selectImages(publicData.place,publicData.tag)">使用</button> | |||
| </div> | |||
| </div> | |||
| <div class="ui container" style="margin-top:50px;text-align:center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChangePublic" | |||
| :current-page="currentPagePublic" | |||
| :page-size="pageSizePublic" | |||
| layout="total, prev, pager, next" | |||
| :total="totalNumPublic"> | |||
| <el-pagination background @current-change="handleCurrentChangePublic" | |||
| :current-page="currentPagePublic" :page-size="pageSizePublic" | |||
| layout="total, prev, pager, next" :total="totalNumPublic"> | |||
| </el-pagination> | |||
| </div> | |||
| </el-tab-pane> | |||
| <el-tab-pane label="我的镜像" name="second" v-loading="loadingCustom"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(customData,index) in tableDataCustom" :key="index"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" | |||
| v-for="(customData,index) in tableDataCustom" :key="index"> | |||
| <div style="width: 90%;"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;"> | |||
| <span class="panel_dataset_name text-over" style="margin-left: 0;">{{customData.tag}} </span> | |||
| <span class="panel_dataset_name text-over" style="margin-left: 0;">{{customData.tag}} | |||
| </span> | |||
| <div v-if="!!customData.topics" class="text-over"> | |||
| <span v-for="(topic,index) in customData.topics" class="ui repo-topic label topic">{{topic}}</span> | |||
| <span v-for="(topic,index) in customData.topics" | |||
| class="ui repo-topic label topic">{{topic}}</span> | |||
| </div> | |||
| </div> | |||
| <div style="margin-top: 8px;display: flex;"> | |||
| <a :title="customData.userName" style="cursor: default;"> | |||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="customData.relAvatarLink"> | |||
| <a v-if="customData.relAvatarLink||customData.userName" :title="customData.userName" | |||
| style="cursor: default;"> | |||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" | |||
| :src="customData.relAvatarLink"> | |||
| </a> | |||
| <a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1" | |||
| style="width: 20px;height: 20px;"></a> | |||
| <span class="panel_datset_desc">{{customData.description}}</span> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button v-if="customData.status===1" class="ui primary basic button mini" @click.stop.prevent="selectImages(customData.place,customData.tag)">使用</button> | |||
| <button v-if="customData.status===1" class="ui primary basic button mini" | |||
| @click.stop.prevent="selectImages(customData.place,customData.tag)">使用</button> | |||
| <span v-if="customData.status===0" style="display: flex;align-items: center;"> | |||
| <i class="CREATING"></i> | |||
| <span style="margin-left: 0.4em;font-size: 12px;color: #5A5A5A;">提交中</span> | |||
| @@ -80,278 +91,286 @@ | |||
| <el-tooltip class="item" effect="dark" content="检测提交镜像是否大小超过20G!" placement="left"> | |||
| <span style="margin-left: 0.4em;font-size: 12px;color:red;">提交失败</span> | |||
| </el-tooltip> | |||
| </span> | |||
| </div> | |||
| </div> | |||
| <div class="ui container" style="margin-top:50px;text-align:center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChangeCustom" | |||
| :current-page="currentPageCustom" | |||
| :page-size="pageSizeCustom" | |||
| layout="total, prev, pager, next" | |||
| :total="totalNumCustom"> | |||
| </el-pagination> | |||
| <el-pagination background @current-change="handleCurrentChangeCustom" | |||
| :current-page="currentPageCustom" :page-size="pageSizeCustom" | |||
| layout="total, prev, pager, next" :total="totalNumCustom"> | |||
| </el-pagination> | |||
| </div> | |||
| </el-tab-pane> | |||
| <el-tab-pane label="我收藏的镜像" name="third"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" v-for="(starData,index) in tableDataStar" :key="index"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;padding: 1rem 0;border-bottom:1px solid #F5F5F5" | |||
| v-for="(starData,index) in tableDataStar" :key="index"> | |||
| <div style="width: 90%;"> | |||
| <div style="display: flex;align-items: center;justify-content: space-between;"> | |||
| <div style="display: flex;align-items: center;"> | |||
| <span class="panel_dataset_name text-over" style="margin-left: 0;">{{starData.tag}} </span> | |||
| <img v-if="starData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;"> | |||
| <span class="panel_dataset_name text-over" style="margin-left: 0;">{{starData.tag}} | |||
| </span> | |||
| <img v-if="starData.type==5" src="/img/jian.svg" style="margin-left: 0.5rem;"> | |||
| </div> | |||
| <div v-if="!!starData.topics" class="text-over"> | |||
| <span v-for="(topic,index) in starData.topics" class="ui repo-topic label topic">{{topic}}</span> | |||
| <span v-for="(topic,index) in starData.topics" | |||
| class="ui repo-topic label topic">{{topic}}</span> | |||
| </div> | |||
| </div> | |||
| <div style="margin-top: 8px;display: flex;"> | |||
| <a :title="starData.userName" style="cursor: default;"> | |||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" :src="starData.relAvatarLink"> | |||
| <a v-if="starData.relAvatarLink||starData.userName" :title="starData.userName" | |||
| style="cursor: default;"> | |||
| <img class="ui avatar mini image" style="width: 20px;height: 20px;" | |||
| :src="starData.relAvatarLink"> | |||
| </a> | |||
| <a v-else><img class="ui avatar mini image" title="Ghost" src="/user/avatar/ghost/-1" | |||
| style="width: 20px;height: 20px;"></a> | |||
| <span class="panel_datset_desc">{{starData.description}}</span> | |||
| </div> | |||
| </div> | |||
| <div> | |||
| <button class="ui primary basic button mini" @click.stop.prevent="selectImages(starData.place,starData.tag)">使用</button> | |||
| <button class="ui primary basic button mini" | |||
| @click.stop.prevent="selectImages(starData.place,starData.tag)">使用</button> | |||
| </div> | |||
| </div> | |||
| <div class="ui container" style="margin-top:50px;text-align:center"> | |||
| <el-pagination | |||
| background | |||
| @current-change="handleCurrentChangeStar" | |||
| :current-page="currentPageStar" | |||
| :page-size="pageSizeStar" | |||
| layout="total, prev, pager, next" | |||
| :total="totalNumStar"> | |||
| </el-pagination> | |||
| <el-pagination background @current-change="handleCurrentChangeStar" | |||
| :current-page="currentPageStar" :page-size="pageSizeStar" layout="total, prev, pager, next" | |||
| :total="totalNumStar"> | |||
| </el-pagination> | |||
| </div> | |||
| </el-tab-pane> | |||
| </el-tabs> | |||
| </el-dialog> | |||
| </div> | |||
| </el-tabs> | |||
| </el-dialog> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| const {_AppSubUrl, _StaticUrlPrefix, csrf} = window.config; | |||
| export default { | |||
| components: { | |||
| }, | |||
| data() { | |||
| return { | |||
| dialogVisible:false, | |||
| benchmarkNew:false, | |||
| imageAddress:'', | |||
| activeName: 'first', | |||
| search:'', | |||
| checked:false, | |||
| currentPagePublic:1, | |||
| pageSizePublic:5, | |||
| totalNumPublic:0, | |||
| paramsPublic:{page:1,pageSize:5,q:'',recommend:false}, | |||
| tableDataPublic: [], | |||
| loadingPublic:false, | |||
| currentPageCustom:1, | |||
| pageSizeCustom:5, | |||
| totalNumCustom:0, | |||
| paramsCustom:{page:1,pageSize:5,q:''}, | |||
| tableDataCustom: [], | |||
| starCustom:[], | |||
| loadingCustom:false, | |||
| currentPageStar:1, | |||
| pageSizeStar:5, | |||
| totalNumStar:0, | |||
| paramsStar:{page:1,pageSize:5,q:''}, | |||
| tableDataStar: [], | |||
| loadingStar:false | |||
| }; | |||
| }, | |||
| methods: { | |||
| handleClick(tab, event) { | |||
| this.search = '' | |||
| if(tab.name=="first"){ | |||
| this.paramsPublic.q = '' | |||
| this.getImageListPublic() | |||
| } | |||
| if(tab.name=="second"){ | |||
| this.getImageListCustom() | |||
| } | |||
| if(tab.name=="third"){ | |||
| this.getImageListStar() | |||
| } | |||
| }, | |||
| tableHeaderStyle({row,column,rowIndex,columnIndex}){ | |||
| if(rowIndex===0){ | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| handleCurrentChangePublic(val){ | |||
| this.paramsPublic.page = val | |||
| this.getImageListPublic() | |||
| }, | |||
| handleCurrentChangeCustom(val){ | |||
| this.paramsCustom.page = val | |||
| this.getImageListCustom() | |||
| }, | |||
| handleCurrentChangeStar(val){ | |||
| this.paramsStar.page = val | |||
| this.getImageListStar() | |||
| }, | |||
| getImageListPublic(){ | |||
| this.loadingPublic = true | |||
| this.$axios.get('/explore/images/public',{ | |||
| params:this.paramsPublic | |||
| }).then((res)=>{ | |||
| this.totalNumPublic = res.data.count | |||
| this.tableDataPublic = res.data.images | |||
| this.loadingPublic = false | |||
| }) | |||
| }, | |||
| getImageListCustom(){ | |||
| this.loadingCustom = true | |||
| this.$axios.get('/explore/images/custom',{ | |||
| params:this.paramsCustom | |||
| }).then((res)=>{ | |||
| this.totalNumCustom = res.data.count | |||
| this.tableDataCustom = res.data.images | |||
| this.tableDataCustom.forEach(element => { | |||
| this.starCustom.push({id:element.id,}) | |||
| }); | |||
| this.loadingCustom = false | |||
| }) | |||
| }, | |||
| getImageListStar(){ | |||
| this.loadingStar = true | |||
| this.$axios.get('/explore/images/star',{ | |||
| params:this.paramsStar | |||
| }).then((res)=>{ | |||
| this.totalNumStar = res.data.count | |||
| this.tableDataStar = res.data.images | |||
| this.loadingStar = false | |||
| }) | |||
| }, | |||
| searchName(){ | |||
| if(this.activeName=='first'){ | |||
| this.paramsPublic.q = this.search | |||
| this.paramsPublic.page = 1 | |||
| const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config; | |||
| export default { | |||
| components: { | |||
| }, | |||
| data() { | |||
| return { | |||
| dialogVisible: false, | |||
| benchmarkNew: false, | |||
| imageAddress: '', | |||
| activeName: 'first', | |||
| search: '', | |||
| checked: false, | |||
| currentPagePublic: 1, | |||
| pageSizePublic: 5, | |||
| totalNumPublic: 0, | |||
| paramsPublic: { page: 1, pageSize: 5, q: '', recommend: false }, | |||
| tableDataPublic: [], | |||
| loadingPublic: false, | |||
| currentPageCustom: 1, | |||
| pageSizeCustom: 5, | |||
| totalNumCustom: 0, | |||
| paramsCustom: { page: 1, pageSize: 5, q: '' }, | |||
| tableDataCustom: [], | |||
| starCustom: [], | |||
| loadingCustom: false, | |||
| currentPageStar: 1, | |||
| pageSizeStar: 5, | |||
| totalNumStar: 0, | |||
| paramsStar: { page: 1, pageSize: 5, q: '' }, | |||
| tableDataStar: [], | |||
| loadingStar: false | |||
| }; | |||
| }, | |||
| methods: { | |||
| handleClick(tab, event) { | |||
| this.search = '' | |||
| if (tab.name == "first") { | |||
| this.paramsPublic.q = '' | |||
| this.getImageListPublic() | |||
| } | |||
| if (tab.name == "second") { | |||
| this.getImageListCustom() | |||
| } | |||
| if (tab.name == "third") { | |||
| this.getImageListStar() | |||
| } | |||
| }, | |||
| tableHeaderStyle({ row, column, rowIndex, columnIndex }) { | |||
| if (rowIndex === 0) { | |||
| return 'background:#f5f5f6;color:#606266' | |||
| } | |||
| }, | |||
| handleCurrentChangePublic(val) { | |||
| this.paramsPublic.page = val | |||
| this.getImageListPublic() | |||
| }, | |||
| handleCurrentChangeCustom(val) { | |||
| this.paramsCustom.page = val | |||
| this.getImageListCustom() | |||
| }, | |||
| handleCurrentChangeStar(val) { | |||
| this.paramsStar.page = val | |||
| this.getImageListStar() | |||
| }, | |||
| getImageListPublic() { | |||
| this.loadingPublic = true | |||
| this.$axios.get('/explore/images/public', { | |||
| params: this.paramsPublic | |||
| }).then((res) => { | |||
| this.totalNumPublic = res.data.count | |||
| this.tableDataPublic = res.data.images | |||
| this.loadingPublic = false | |||
| }) | |||
| }, | |||
| getImageListCustom() { | |||
| this.loadingCustom = true | |||
| this.$axios.get('/explore/images/custom', { | |||
| params: this.paramsCustom | |||
| }).then((res) => { | |||
| this.totalNumCustom = res.data.count | |||
| this.tableDataCustom = res.data.images | |||
| this.tableDataCustom.forEach(element => { | |||
| this.starCustom.push({ id: element.id, }) | |||
| }); | |||
| this.loadingCustom = false | |||
| }) | |||
| }, | |||
| getImageListStar() { | |||
| this.loadingStar = true | |||
| this.$axios.get('/explore/images/star', { | |||
| params: this.paramsStar | |||
| }).then((res) => { | |||
| this.totalNumStar = res.data.count | |||
| this.tableDataStar = res.data.images | |||
| this.loadingStar = false | |||
| }) | |||
| }, | |||
| searchName() { | |||
| if (this.activeName == 'first') { | |||
| this.paramsPublic.q = this.search | |||
| this.paramsPublic.page = 1 | |||
| this.getImageListPublic() | |||
| } | |||
| if (this.activeName == 'second') { | |||
| this.paramsCustom.q = this.search | |||
| this.paramsCustom.page = 1 | |||
| this.getImageListCustom() | |||
| } | |||
| if (this.activeName == 'third') { | |||
| this.paramsStar.q = this.search | |||
| this.paramsStar.page = 1 | |||
| this.getImageListStar() | |||
| } | |||
| }, | |||
| selectImages(place) { | |||
| this.imageAddress = place | |||
| this.dialogVisible = false | |||
| }, | |||
| }, | |||
| watch: { | |||
| search(val) { | |||
| if (this.activeName == 'first') { | |||
| this.paramsPublic.q = val | |||
| this.getImageListPublic() | |||
| } | |||
| if (this.activeName == 'second') { | |||
| this.paramsCustom.q = val | |||
| this.getImageListCustom() | |||
| } | |||
| if (this.activeName == 'third') { | |||
| this.paramsStar.q = val | |||
| this.getImageListStar() | |||
| } | |||
| } | |||
| }, | |||
| mounted() { | |||
| this.getImageListPublic() | |||
| if (location.href.indexOf('benchmark') !== -1 || location.href.indexOf('train-job') !== -1) { | |||
| this.benchmarkNew = true | |||
| } | |||
| }, | |||
| created() { | |||
| } | |||
| if(this.activeName=='second'){ | |||
| this.paramsCustom.q = this.search | |||
| this.paramsCustom.page = 1 | |||
| this.getImageListCustom() | |||
| } | |||
| if(this.activeName=='third'){ | |||
| this.paramsStar.q = this.search | |||
| this.paramsStar.page = 1 | |||
| this.getImageListStar() | |||
| } | |||
| }, | |||
| selectImages(place){ | |||
| this.imageAddress = place | |||
| this.dialogVisible = false | |||
| }, | |||
| }, | |||
| watch:{ | |||
| search(val){ | |||
| if(this.activeName=='first'){ | |||
| this.paramsPublic.q = val | |||
| this.getImageListPublic() | |||
| } | |||
| if(this.activeName=='second'){ | |||
| this.paramsCustom.q = val | |||
| this.getImageListCustom() | |||
| } | |||
| if(this.activeName=='third'){ | |||
| this.paramsStar.q = val | |||
| this.getImageListStar() | |||
| } | |||
| } | |||
| }, | |||
| mounted() { | |||
| this.getImageListPublic() | |||
| if(location.href.indexOf('benchmark')!==-1 || location.href.indexOf('train-job')!==-1){ | |||
| this.benchmarkNew = true | |||
| } | |||
| }, | |||
| created() { | |||
| } | |||
| }; | |||
| }; | |||
| </script> | |||
| <style scoped> | |||
| .header-wrapper { | |||
| background-color: #f5f5f6; | |||
| padding-top: 15px; | |||
| } | |||
| .image_text{ | |||
| padding:25px 0 55px 0 ; | |||
| } | |||
| #header{ | |||
| position: relative; | |||
| top:-40px; | |||
| } | |||
| #success{ | |||
| background-color: #5bb973; | |||
| color: white; | |||
| } | |||
| .text-over{ | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| vertical-align: middle; | |||
| white-space: nowrap; | |||
| } | |||
| .image_title{ | |||
| display: inline-block; | |||
| width: 80%; | |||
| cursor: default; | |||
| color: rgb(66, 98, 144); | |||
| } | |||
| .image_desc{ | |||
| -webkit-line-clamp: 2; | |||
| -webkit-box-orient: vertical; | |||
| display: -webkit-box; | |||
| text-overflow: ellipsis; | |||
| overflow: hidden; | |||
| } | |||
| .heart-stroke{ | |||
| stroke: #666; | |||
| stroke-width: 2; | |||
| fill: #fff | |||
| } | |||
| .stars_active{ | |||
| fill: #FA8C16 !important; | |||
| stroke:#FA8C16 !important | |||
| } | |||
| </style> | |||
| .header-wrapper { | |||
| background-color: #f5f5f6; | |||
| padding-top: 15px; | |||
| } | |||
| .image_text { | |||
| padding: 25px 0 55px 0; | |||
| } | |||
| #header { | |||
| position: relative; | |||
| top: -40px; | |||
| } | |||
| #success { | |||
| background-color: #5bb973; | |||
| color: white; | |||
| } | |||
| .text-over { | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| vertical-align: middle; | |||
| white-space: nowrap; | |||
| } | |||
| .image_title { | |||
| display: inline-block; | |||
| width: 80%; | |||
| cursor: default; | |||
| color: rgb(66, 98, 144); | |||
| } | |||
| .image_desc { | |||
| -webkit-line-clamp: 2; | |||
| -webkit-box-orient: vertical; | |||
| display: -webkit-box; | |||
| text-overflow: ellipsis; | |||
| overflow: hidden; | |||
| } | |||
| .heart-stroke { | |||
| stroke: #666; | |||
| stroke-width: 2; | |||
| fill: #fff | |||
| } | |||
| .stars_active { | |||
| fill: #FA8C16 !important; | |||
| stroke: #FA8C16 !important | |||
| } | |||
| </style> | |||
| @@ -2,7 +2,7 @@ export default async function initClipboard() { | |||
| const els = document.querySelectorAll('.clipboard'); | |||
| if (!els || !els.length) return; | |||
| const {default: ClipboardJS} = await import(/* webpackChunkName: "clipboard" */'clipboard'); | |||
| const { default: ClipboardJS } = await import(/* webpackChunkName: "clipboard" */'clipboard'); | |||
| const clipboard = new ClipboardJS(els); | |||
| clipboard.on('success', (e) => { | |||
| @@ -2,7 +2,9 @@ export default async function initCloudrain() { | |||
| let debug_button = $('.cloudbrain_debug').data('debug') | |||
| let debug_again_button = $('.cloudbrain_debug').data('debug-again') | |||
| let timeid = window.setInterval(loadJobStatus, 15000); | |||
| let timeidShow = window.setInterval(loadShowJobStatus, 15000); | |||
| $(document).ready(loadJobStatus); | |||
| $(document).ready(loadShowJobStatus); | |||
| function loadJobStatus() { | |||
| $(".job-status").each((index, job) => { | |||
| const ID = job.dataset.jobid; | |||
| @@ -10,7 +12,7 @@ export default async function initCloudrain() { | |||
| // const computeResource = job.dataset.resource | |||
| const versionname = job.dataset.version | |||
| const status_text = $(`#${ID}-text`).text() | |||
| const finalState = ['STOPPED','CREATE_FAILED','UNAVAILABLE','DELETED','RESIZE_FAILED','SUCCEEDED','IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED','SUBMIT_MODEL_FAILED','DEPLOY_SERVICE_FAILED','CHECK_FAILED'] | |||
| const finalState = ['STOPPED', 'CREATE_FAILED', 'UNAVAILABLE', 'DELETED', 'RESIZE_FAILED', 'SUCCEEDED', 'IMAGE_FAILED', 'SUBMIT_FAILED', 'DELETE_FAILED', 'KILLED', 'COMPLETED', 'FAILED', 'CANCELED', 'LOST', 'START_FAILED', 'SUBMIT_MODEL_FAILED', 'DEPLOY_SERVICE_FAILED', 'CHECK_FAILED'] | |||
| if (finalState.includes(status_text)) { | |||
| return | |||
| } | |||
| @@ -19,46 +21,83 @@ export default async function initCloudrain() { | |||
| const ID = data.ID || data.JobID | |||
| const status = data.JobStatus | |||
| const duration = data.JobDuration | |||
| $('#duration-'+ID).text(duration) | |||
| console.log(status,["STOPPED"].includes(status)) | |||
| $('#duration-' + ID).text(duration) | |||
| if (status != status_text) { | |||
| $('#' + ID+'-icon').removeClass().addClass(status) | |||
| $('#' + ID+ '-text').text(status) | |||
| $('#' + ID + '-icon').removeClass().addClass(status) | |||
| $('#' + ID + '-text').text(status) | |||
| finalState.includes(status) && $('#' + ID + '-stop').removeClass('blue').addClass('disabled') | |||
| } | |||
| if(status==="RUNNING"){ | |||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text(debug_button).css("margin","0 1rem") | |||
| $('#model-image-'+ID).removeClass('disabled').addClass('blue') | |||
| if (status === "RUNNING") { | |||
| $('#ai-debug-' + ID).removeClass('disabled').addClass('blue').text(debug_button).css("margin", "0 1rem") | |||
| $('#model-image-' + ID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(status!=="RUNNING"){ | |||
| if (status !== "RUNNING") { | |||
| // $('#model-debug-'+ID).removeClass('blue') | |||
| // $('#model-debug-'+ID).addClass('disabled') | |||
| $('#model-image-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#model-image-' + ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(["CREATING","STOPPING","WAITING","STARTING"].includes(status)){ | |||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| if (["CREATING", "STOPPING", "WAITING", "STARTING"].includes(status)) { | |||
| $('#ai-debug-' + ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| if(['STOPPED','FAILED','START_FAILED','CREATE_FAILED','SUCCEEDED'].includes(status)){ | |||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin","0") | |||
| } | |||
| if(["RUNNING","WAITING"].includes(status)){ | |||
| $('#ai-stop-'+ID).removeClass('disabled').addClass('blue') | |||
| if (['STOPPED', 'FAILED', 'START_FAILED', 'CREATE_FAILED', 'SUCCEEDED'].includes(status)) { | |||
| $('#ai-debug-' + ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin", "0") | |||
| } | |||
| if(["CREATING","STOPPING","STARTING","STOPPED","FAILED","START_FAILED","SUCCEEDED","COMPLETED","CREATE_FAILED"].includes(status)){ | |||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||
| if (["RUNNING", "WAITING"].includes(status)) { | |||
| $('#ai-stop-' + ID).removeClass('disabled').addClass('blue') | |||
| } | |||
| if(["STOPPED","FAILED","START_FAILED","KILLED","COMPLETED","SUCCEEDED"].includes(status)){ | |||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||
| }else{ | |||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | |||
| if (["CREATING", "STOPPING", "STARTING", "STOPPED", "FAILED", "START_FAILED", "SUCCEEDED", "COMPLETED", "CREATE_FAILED"].includes(status)) { | |||
| $('#ai-stop-' + ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }).fail(function(err) { | |||
| if (["STOPPED", "FAILED", "START_FAILED", "KILLED", "COMPLETED", "SUCCEEDED"].includes(status)) { | |||
| $('#ai-delete-' + ID).removeClass('disabled').addClass('blue') | |||
| } else { | |||
| $('#ai-delete-' + ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| }); | |||
| }; | |||
| function assertDelete(obj,versionName,repoPath) { | |||
| function loadShowJobStatus() { | |||
| $(".ui.accordion.border-according").each((index, job) => { | |||
| const jobID = job.dataset.jobid; | |||
| const repoPath = job.dataset.repopath; | |||
| const versionname = job.dataset.version | |||
| // ['IMAGE_FAILED','SUBMIT_FAILED','DELETE_FAILED','KILLED','COMPLETED','FAILED','CANCELED','LOST','START_FAILED'] | |||
| // if (job.textContent.trim() == 'IMAGE_FAILED' || job.textContent.trim() == 'SUBMIT_FAILED' || job.textContent.trim() == 'DELETE_FAILED' | |||
| // || job.textContent.trim() == 'KILLED' || job.textContent.trim() == 'COMPLETED' || job.textContent.trim() == 'FAILED' | |||
| // || job.textContent.trim() == 'CANCELED' || job.textContent.trim() == 'LOST') { | |||
| // return | |||
| // } | |||
| let status = $(`#${versionname}-status-span`).text() | |||
| if (['IMAGE_FAILED', 'SUBMIT_FAILED', 'DELETE_FAILED', 'KILLED', 'COMPLETED', 'FAILED', 'CANCELED', 'LOST', 'START_FAILED', 'SUCCEEDED', 'STOPPED'].includes(status)) { | |||
| return | |||
| } | |||
| let stopArray = ["KILLED", "FAILED", "START_FAILED", "KILLING", "COMPLETED", "SUCCEEDED", "STOPPED"] | |||
| $.get(`/api/v1/repos/${repoPath}/${jobID}?version_name=${versionname}`, (data) => { | |||
| //$(`#${versionname}-duration-span`).text(data.JobDuration) | |||
| $(`#${versionname}-status-span span`).text(data.JobStatus) | |||
| $(`#${versionname}-status-span i`).attr("class", data.JobStatus) | |||
| // detail status and duration | |||
| //$('#'+versionname+'-duration').text(data.JobDuration) | |||
| $('#' + versionname + '-status').text(data.JobStatus) | |||
| if (stopArray.includes(data.JobStatus)) { | |||
| $('#' + versionname + '-stop').addClass('disabled') | |||
| } | |||
| if (data.JobStatus === "COMPLETED") { | |||
| $('#' + versionname + '-create-model').removeClass('disabled').addClass('blue') | |||
| } | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| }); | |||
| }; | |||
| function assertDelete(obj, versionName, repoPath) { | |||
| if (obj.style.color == "rgb(204, 204, 204)") { | |||
| return | |||
| } else { | |||
| @@ -66,19 +105,19 @@ export default async function initCloudrain() { | |||
| let flag = 1; | |||
| $('.ui.basic.modal') | |||
| .modal({ | |||
| onDeny: function() { | |||
| onDeny: function () { | |||
| flag = false | |||
| }, | |||
| onApprove: function() { | |||
| if(!versionName){ | |||
| onApprove: function () { | |||
| if (!versionName) { | |||
| document.getElementById(delId).submit() | |||
| } | |||
| else{ | |||
| deleteVersion(versionName,repoPath) | |||
| else { | |||
| deleteVersion(versionName, repoPath) | |||
| } | |||
| flag = true | |||
| }, | |||
| onHidden: function() { | |||
| onHidden: function () { | |||
| if (flag == false) { | |||
| $('.alert').html('您已取消操作').removeClass('alert-success').addClass('alert-danger').show().delay(1500).fadeOut(); | |||
| } | |||
| @@ -87,157 +126,205 @@ export default async function initCloudrain() { | |||
| .modal('show') | |||
| } | |||
| } | |||
| function deleteVersion(versionName,repoPath){ | |||
| function deleteVersion(versionName, repoPath) { | |||
| const url = `/api/v1/repos/${repoPath}` | |||
| $.post(url,{version_name:versionName},(data)=>{ | |||
| if(data.StatusOK===0){ | |||
| $.post(url, { version_name: versionName }, (data) => { | |||
| if (data.StatusOK === 0) { | |||
| location.reload() | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| $('.ui.basic.ai_delete').click(function() { | |||
| $('.ui.basic.ai_delete').click(function () { | |||
| const repoPath = this.dataset.repopath | |||
| const versionName = this.dataset.version | |||
| if(repoPath && versionName){ | |||
| assertDelete(this,versionName,repoPath) | |||
| if (repoPath && versionName) { | |||
| assertDelete(this, versionName, repoPath) | |||
| } | |||
| else{ | |||
| else { | |||
| assertDelete(this) | |||
| } | |||
| }) | |||
| function stopDebug(ID,stopUrl){ | |||
| function stopDebug(ID, stopUrl) { | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:stopUrl, | |||
| data:$('#stopForm-'+ID).serialize(), | |||
| success:function(res){ | |||
| if(res.result_code==="0"){ | |||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + ID+ '-text').text(res.status) | |||
| if(res.status==="STOPPED"){ | |||
| $('#ai-debug-'+ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin","0") | |||
| $('#ai-image-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-model-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||
| type: "POST", | |||
| url: stopUrl, | |||
| data: $('#stopForm-' + ID).serialize(), | |||
| success: function (res) { | |||
| if (res.result_code === "0") { | |||
| $('#' + ID + '-icon').removeClass().addClass(res.status) | |||
| $('#' + ID + '-text').text(res.status) | |||
| if (res.status === "STOPPED") { | |||
| $('#ai-debug-' + ID).removeClass('disabled').addClass('blue').text(debug_again_button).css("margin", "0") | |||
| $('#ai-image-' + ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-model-debug-' + ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-' + ID).removeClass('disabled').addClass('blue') | |||
| $('#ai-stop-' + ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| else{ | |||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-'+ID).removeClass('blue').addClass('disabled') | |||
| else { | |||
| $('#ai-debug-' + ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-stop-' + ID).removeClass('blue').addClass('disabled') | |||
| } | |||
| }else{ | |||
| } else { | |||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
| } | |||
| }, | |||
| error :function(res){ | |||
| error: function (res) { | |||
| console.log(res) | |||
| } | |||
| }) | |||
| } | |||
| $('.ui.basic.ai_stop').click(function() { | |||
| $('.ui.basic.ai_stop').click(function () { | |||
| const ID = this.dataset.jobid | |||
| const repoPath = this.dataset.repopath | |||
| stopDebug(ID,repoPath) | |||
| stopDebug(ID, repoPath) | |||
| }) | |||
| function stopVersion(version_name,ID,repoPath){ | |||
| function stopVersion(version_name, ID, repoPath) { | |||
| const url = `/api/v1/repos/${repoPath}/${ID}/stop_version` | |||
| $.post(url,{version_name:version_name},(data)=>{ | |||
| if(data.StatusOK===0){ | |||
| $('#ai-stop-'+ID).removeClass('blue') | |||
| $('#ai-stop-'+ID).addClass('disabled') | |||
| refreshStatus(version_name,ID,repoPath) | |||
| $.post(url, { version_name: version_name }, (data) => { | |||
| if (data.StatusOK === 0) { | |||
| $('#ai-stop-' + ID).removeClass('blue') | |||
| $('#ai-stop-' + ID).addClass('disabled') | |||
| refreshStatus(version_name, ID, repoPath) | |||
| } | |||
| }).fail(function(err) { | |||
| console.log(err); | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| function refreshStatus(version_name,ID,repoPath){ | |||
| function refreshStatus(version_name, ID, repoPath) { | |||
| const url = `/api/v1/repos/${repoPath}/${ID}/?version_name${version_name}` | |||
| $.get(url,(data)=>{ | |||
| $(`#${ID}-icon`).attr("class",data.JobStatus) | |||
| $.get(url, (data) => { | |||
| $(`#${ID}-icon`).attr("class", data.JobStatus) | |||
| // detail status and duration | |||
| $(`#${ID}-text`).text(data.JobStatus) | |||
| if(["STOPPED","FAILED","START_FAILED","KILLED","COMPLETED","SUCCEEDED"].includes(data.JobStatus)){ | |||
| $('#ai-delete-'+ID).removeClass('disabled').addClass('blue') | |||
| if (["STOPPED", "FAILED", "START_FAILED", "KILLED", "COMPLETED", "SUCCEEDED"].includes(data.JobStatus)) { | |||
| $('#ai-delete-' + ID).removeClass('disabled').addClass('blue') | |||
| } | |||
| }).fail(function(err) { | |||
| }).fail(function (err) { | |||
| console.log(err); | |||
| }); | |||
| } | |||
| $('.ui.basic.ai_stop_version').click(function() { | |||
| $('.ui.basic.ai_stop_version').click(function () { | |||
| const ID = this.dataset.jobid | |||
| const repoPath = this.dataset.repopath | |||
| const versionName = this.dataset.version | |||
| stopVersion(versionName,ID,repoPath) | |||
| stopVersion(versionName, ID, repoPath) | |||
| }) | |||
| function getModelInfo(repoPath,modelName,versionName,jobName){ | |||
| $.get(`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`,(data)=>{ | |||
| if(data.length===0){ | |||
| function getModelInfo(repoPath, modelName, versionName, jobName) { | |||
| $.get(`${repoPath}/modelmanage/show_model_info_api?name=${modelName}`, (data) => { | |||
| if (data.length === 0) { | |||
| $(`#${jobName}`).popup('toggle') | |||
| }else{ | |||
| let versionData = data.filter((item)=>{ | |||
| } else { | |||
| let versionData = data.filter((item) => { | |||
| return item.Version === versionName | |||
| }) | |||
| if(versionData.length==0){ | |||
| if (versionData.length == 0) { | |||
| $(`#${jobName}`).popup('toggle') | |||
| } | |||
| else{ | |||
| else { | |||
| location.href = `${repoPath}/modelmanage/show_model_info?name=${modelName}` | |||
| } | |||
| } | |||
| }) | |||
| } | |||
| $('.goto_modelmanage').click(function() { | |||
| $('.goto_modelmanage').click(function () { | |||
| const repoPath = this.dataset.repopath | |||
| const modelName = this.dataset.modelname | |||
| const versionName = this.dataset.version | |||
| const jobName = this.dataset.jobname | |||
| getModelInfo(repoPath,modelName,versionName,jobName) | |||
| getModelInfo(repoPath, modelName, versionName, jobName) | |||
| }) | |||
| function debugAgain(ID,debugUrl,redirect_to){ | |||
| if($('#' + ID+ '-text').text()==="RUNNING"){ | |||
| window.open(debugUrl+'debug') | |||
| }else{ | |||
| function debugAgain(ID, debugUrl, redirect_to) { | |||
| if ($('#' + ID + '-text').text() === "RUNNING") { | |||
| window.open(debugUrl + 'debug') | |||
| } else { | |||
| $.ajax({ | |||
| type:"POST", | |||
| url:debugUrl+'restart?redirect_to='+redirect_to, | |||
| data:$('#debugAgainForm-'+ID).serialize(), | |||
| success:function(res){ | |||
| if(res['WechatRedirectUrl']){ | |||
| window.location.href=res['WechatRedirectUrl'] | |||
| type: "POST", | |||
| url: debugUrl + 'restart?redirect_to=' + redirect_to, | |||
| data: $('#debugAgainForm-' + ID).serialize(), | |||
| success: function (res) { | |||
| if (res['WechatRedirectUrl']) { | |||
| window.location.href = res['WechatRedirectUrl'] | |||
| } | |||
| else if(res.result_code==="0"){ | |||
| if(res.id!==ID){ | |||
| else if (res.result_code === "0") { | |||
| if (res.id !== ID) { | |||
| location.reload() | |||
| }else{ | |||
| $('#' + ID+'-icon').removeClass().addClass(res.status) | |||
| $('#' + ID+ '-text').text(res.status) | |||
| $('#ai-debug-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-'+ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-'+ID).text(debug_button).css("margin","0 1rem") | |||
| } else { | |||
| $('#' + ID + '-icon').removeClass().addClass(res.status) | |||
| $('#' + ID + '-text').text(res.status) | |||
| $('#ai-debug-' + ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-delete-' + ID).removeClass('blue').addClass('disabled') | |||
| $('#ai-debug-' + ID).text(debug_button).css("margin", "0 1rem") | |||
| } | |||
| }else{ | |||
| } else { | |||
| $('.alert').html(res.error_msg).removeClass('alert-success').addClass('alert-danger').show().delay(2000).fadeOut(); | |||
| } | |||
| }, | |||
| error :function(res){ | |||
| error: function (res) { | |||
| console.log(res) | |||
| } | |||
| }) | |||
| } | |||
| } | |||
| $('.ui.basic.ai_debug').click(function() { | |||
| $('.ui.basic.ai_debug').click(function () { | |||
| const ID = this.dataset.jobid | |||
| const repoPath = this.dataset.repopath | |||
| const redirect_to = this.dataset.linkpath | |||
| debugAgain(ID,repoPath,redirect_to) | |||
| debugAgain(ID, repoPath, redirect_to) | |||
| }) | |||
| } | |||
| function userSearchControll() { | |||
| if ($('#userCloud').length === 0) { | |||
| return | |||
| } | |||
| const params = new URLSearchParams(window.location.search) | |||
| let jobType | |||
| if ($('.cloudbrain_debug').length === 1) { | |||
| if (!params.get('jobType')) { | |||
| jobType = $('.cloudbrain_debug').data('allTask') | |||
| } else { | |||
| if (params.get('jobType') === 'DEBUG') { | |||
| jobType = $('.cloudbrain_debug').data('debug-task') | |||
| } else if (params.get('jobType') === 'TRAIN') { | |||
| jobType = $('.cloudbrain_debug').data('train-task') | |||
| } | |||
| else if (params.get('jobType') === 'INFERENCE') { | |||
| jobType = $('.cloudbrain_debug').data('inference-task') | |||
| } | |||
| else { | |||
| jobType = $('.cloudbrain_debug').data('benchmark-task') | |||
| } | |||
| } | |||
| } | |||
| let listType = !params.get('listType') ? $('.cloudbrain_debug').data('all-compute') : params.get('listType') | |||
| let jobStatus = !params.get('jobStatus') ? $('.cloudbrain_debug').data('all-status') : params.get('jobStatus').toUpperCase() | |||
| const dropdownValueArray = [jobType, listType, jobStatus] | |||
| $('#userCloud .default.text ').each(function (index, e) { | |||
| $(e).text(dropdownValueArray[index]) | |||
| }) | |||
| } | |||
| function AdaminSearchControll() { | |||
| if ($('#adminCloud').length === 0) { | |||
| return | |||
| } | |||
| const params = new URLSearchParams(window.location.search) | |||
| let jobType = !params.get('jobType') ? $('.cloudbrain_debug').data('all-task') : params.get('jobType') | |||
| let listType = !params.get('listType') ? $('.cloudbrain_debug').data('all-compute') : params.get('listType') | |||
| let jobStatus = !params.get('jobStatus') ? $('.cloudbrain_debug').data('all-status') : params.get('jobStatus').toUpperCase() | |||
| const dropdownValueArray = [jobType, listType, jobStatus] | |||
| $('#adminCloud .default.text ').each(function (index, e) { | |||
| $(e).text(dropdownValueArray[index]) | |||
| }) | |||
| } | |||
| userSearchControll() | |||
| AdaminSearchControll() | |||
| @@ -0,0 +1,156 @@ | |||
| export default async function initContextMenu() { | |||
| $('.popup-close').on('click', function (e) { | |||
| $(this).parents('tr').prev().css('display', 'table-row') | |||
| $(this).closest('tr').css('cssText', 'display:none !important') | |||
| }) | |||
| function contextMenu() { | |||
| let canContextMenu = $('.ui.single.line.table.can-context-menu').data('can-editfile') | |||
| if (canContextMenu) { | |||
| $('.name.four.wide').on('contextmenu', function (e) { | |||
| let ev = window.event || e; | |||
| ev.preventDefault(); | |||
| menu.show(e) | |||
| }) | |||
| } else { | |||
| return | |||
| } | |||
| } | |||
| contextMenu() | |||
| const menu = new Menu({ | |||
| data: [ | |||
| { | |||
| label: '新标签打开', | |||
| icon: "file outline icon context-menu-icon", | |||
| active: (e, a) => { | |||
| window.open(a.currentTarget.getElementsByTagName("a")[0].getAttribute('href')) | |||
| } | |||
| }, | |||
| { | |||
| label: '重命名', | |||
| icon: "edit icon context-menu-icon", | |||
| active: (e, a) => { | |||
| document.querySelectorAll(".context-menu-one").forEach((ele) => { | |||
| if (ele.style.display === 'table-row') { | |||
| ele.style.display = 'none' | |||
| ele.previousElementSibling.style.display = 'table-row' | |||
| } | |||
| }) | |||
| if (a.currentTarget.parentNode.nextElementSibling) { | |||
| a.currentTarget.parentNode.style.setProperty('display', 'none', 'important') | |||
| a.currentTarget.parentNode.nextElementSibling.style.display = 'table-row' | |||
| const renameFile = a.currentTarget.getElementsByTagName("a")[0].getAttribute('title') | |||
| let renameFileValue = renameFile.indexOf('/') !== -1 ? renameFile.substr(0, renameFile.indexOf('/')) : renameFile | |||
| a.currentTarget.parentNode.nextElementSibling.getElementsByTagName("input")[0].setAttribute("value", renameFileValue) | |||
| } | |||
| let btn = a.currentTarget.parentNode.nextElementSibling.getElementsByTagName("button")[0] | |||
| btn.addEventListener('click', function (e) { | |||
| let postUrl = btn.getAttribute('data-postbasepath') | |||
| const postUrlArr = postUrl.split('/') | |||
| postUrlArr[postUrlArr.length - 1] = encodeURIComponent(postUrlArr[postUrlArr.length - 1]) | |||
| postUrl = postUrlArr.join('/') | |||
| console.log(postUrl) | |||
| let last_commit = btn.getAttribute('data-commit') | |||
| let tree_path = btn.getAttribute('data-treepath') + e.target.parentNode.previousElementSibling.getElementsByTagName("input")[0].value | |||
| let csrf = $("input[name='_csrf']").val() | |||
| $.ajax({ | |||
| url: postUrl, | |||
| type: "POST", | |||
| contentType: "application/x-www-form-urlencoded", | |||
| data: { last_commit: last_commit, tree_path: tree_path, _csrf: csrf }, | |||
| success: function (res) { | |||
| if (res.Code === 0) { | |||
| document.getElementById("mask").style.display = "block" | |||
| location.reload() | |||
| } | |||
| else { | |||
| $('.ui.negative.message').text(res.Msg).show().delay(10000).fadeOut(); | |||
| } | |||
| } | |||
| }) | |||
| }) | |||
| }, | |||
| }, | |||
| // { | |||
| // label: '删除', | |||
| // icon: "trash icon context-menu-icon", | |||
| // active: (e, a) => { | |||
| // console.dir(a) | |||
| // $('.context-menu-delete.modal') | |||
| // .modal({ | |||
| // onApprove() { | |||
| // } | |||
| // }) | |||
| // .modal('show'); | |||
| // } | |||
| // }, | |||
| ] | |||
| }) | |||
| } | |||
| class Menu { | |||
| constructor(param) { | |||
| this.target = document.createElement('div') | |||
| this.target.classList.add("ui", "menu", "compact", "vertical", "context-menu-click") | |||
| this.data = param.data | |||
| this.active = false | |||
| this.clickZ = this.click.bind(this) | |||
| this.closeZ = this.close2.bind(this) | |||
| document.addEventListener('click', this.closeZ) | |||
| for (let i = 0; i < this.data.length; i++) { | |||
| let div = document.createElement('a') | |||
| div.classList.add('item', 'context-menu-operation') | |||
| if (this.data[i].disabled) { | |||
| div.classList.add('disabled') | |||
| } | |||
| div.dataset.index = i.toString() | |||
| div.innerHTML = `<i class="${this.data[i].icon}"></i>${this.data[i].label}` | |||
| div.addEventListener('click', this.clickZ) | |||
| this.target.append(div) | |||
| } | |||
| document.body.append(this.target) | |||
| } | |||
| click(e) { | |||
| let index = parseInt(e.target.dataset.index) | |||
| if (this.data[index].active) { | |||
| this.data[index].active(e, this.acEvent) | |||
| } | |||
| this.close() | |||
| } | |||
| show(e) { | |||
| this.active = true | |||
| this.nodeList = this.target.querySelectorAll('.item') | |||
| for (let i = 0; i < this.data.length; i++) { | |||
| if (this.data[i].beforeDisabled) { | |||
| let t = this.data[i].beforeDisabled(e) | |||
| this.data[i].disabled = t | |||
| if (t) { | |||
| this.nodeList[i].classList.add('disabled') | |||
| } else { | |||
| this.nodeList[i].classList.remove('disabled') | |||
| } | |||
| } | |||
| } | |||
| this.acEvent = e | |||
| this.target.style.top = `${e.pageY}px` | |||
| this.target.style.left = `${e.pageX}px` | |||
| this.target.style.minWidth = '90px' | |||
| this.target.classList.add('active') | |||
| } | |||
| close() { | |||
| this.active = false | |||
| this.target.classList.remove('active') | |||
| } | |||
| close2(e) { | |||
| if (!this.target.contains(e.target) && this.active) { | |||
| this.active = false | |||
| this.target.classList.remove('active') | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,64 @@ | |||
| import Vue from 'vue' | |||
| import Router from 'vue-router' | |||
| import DataAnalysis from '../components/DataAnalysis.vue' | |||
| import ProAnalysis from '../components/ProAnalysis.vue' | |||
| import ProTrend from '../components/ProTrend.vue' | |||
| import UserTrend from '../components/UserTrend.vue' | |||
| import UserAnalysis from '../components/UserAnalysis.vue' | |||
| import BrainAnalysis from '../components/BrainAnalysis.vue' | |||
| import Overview from '../components/Overview.vue' | |||
| const originalPush = Router.prototype.push | |||
| Router.prototype.push = function push(location) { | |||
| return originalPush.call(this, location).catch(err => err) | |||
| } | |||
| Vue.use(Router) | |||
| export default new Router({ | |||
| mode: 'history', | |||
| base: '/explore/data_analysis/', //添加根目录 | |||
| scrollBehavior: () => ({ y: 0 }), | |||
| routes:[ | |||
| { | |||
| path:'/',redirect:'/ProAnalysis', | |||
| name:'ProAnalysis', | |||
| component:ProAnalysis, | |||
| }, | |||
| { | |||
| path:'/Overview', | |||
| name:'Overview', | |||
| component:Overview, | |||
| }, | |||
| { | |||
| path:'/ProTrend', | |||
| name:'ProTrend', | |||
| component:ProTrend, | |||
| }, | |||
| { | |||
| path:'/ProAnalysis', | |||
| name:'ProAnalysis', | |||
| component:ProAnalysis, | |||
| }, | |||
| { | |||
| path:'/UserAnalysis', | |||
| name:'UserAnalysis', | |||
| component:UserAnalysis, | |||
| }, | |||
| { | |||
| path:'/UserTrend', | |||
| name:'UserTrend', | |||
| component:UserTrend, | |||
| }, | |||
| { | |||
| path:'/BrainAnalysis', | |||
| name:'BrainAnalysis', | |||
| component:BrainAnalysis, | |||
| }, | |||
| ], | |||
| }) | |||
| @@ -1025,4 +1025,33 @@ display: block; | |||
| z-index: 9999; | |||
| width:150; | |||
| height: 80; | |||
| } | |||
| } | |||
| .ui.toast-container .toast-box.compact, .ui.toast-container .toast-box>.compact { | |||
| width: 250px !important; | |||
| } | |||
| .context-menu-click { | |||
| z-index: 99; | |||
| position: absolute; | |||
| padding: 0; | |||
| border-radius: 4px; | |||
| border: 1px solid #e3e9ed; | |||
| -webkit-box-shadow: none; | |||
| box-shadow: none; | |||
| background: #fff; | |||
| display: none !important; | |||
| } | |||
| .context-menu-click.active { | |||
| display: block !important; | |||
| } | |||
| .context-menu-operation { | |||
| padding: 5px !important; | |||
| line-height: 1.78 !important; | |||
| } | |||
| .context-menu-icon { | |||
| float: left !important; | |||
| margin: 0px 5px 0px 0px !important; | |||
| } | |||