| @@ -8,13 +8,14 @@ import ( | |||||
| "strings" | "strings" | ||||
| "time" | "time" | ||||
| "code.gitea.io/gitea/modules/util" | |||||
| "xorm.io/builder" | "xorm.io/builder" | ||||
| "xorm.io/xorm" | "xorm.io/xorm" | ||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/setting" | "code.gitea.io/gitea/modules/setting" | ||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| "code.gitea.io/gitea/modules/util" | |||||
| ) | ) | ||||
| type CloudbrainStatus string | type CloudbrainStatus string | ||||
| @@ -142,7 +143,7 @@ type Cloudbrain struct { | |||||
| VersionID int64 //版本id | VersionID int64 //版本id | ||||
| VersionName string `xorm:"INDEX"` //当前版本 | VersionName string `xorm:"INDEX"` //当前版本 | ||||
| Uuid string //数据集id | Uuid string //数据集id | ||||
| DatasetName string | |||||
| DatasetName string `xorm:"varchar(2000)"` | |||||
| VersionCount int //任务的当前版本数量,不包括删除的 | VersionCount int //任务的当前版本数量,不包括删除的 | ||||
| IsLatestVersion string //是否是最新版本,1是,0否 | IsLatestVersion string //是否是最新版本,1是,0否 | ||||
| CommitID string //提交的仓库代码id | CommitID string //提交的仓库代码id | ||||
| @@ -6,6 +6,8 @@ import ( | |||||
| "sort" | "sort" | ||||
| "strings" | "strings" | ||||
| "code.gitea.io/gitea/modules/setting" | |||||
| "code.gitea.io/gitea/modules/log" | "code.gitea.io/gitea/modules/log" | ||||
| "code.gitea.io/gitea/modules/timeutil" | "code.gitea.io/gitea/modules/timeutil" | ||||
| @@ -178,7 +180,7 @@ type SearchDatasetOptions struct { | |||||
| Category string | Category string | ||||
| Task string | Task string | ||||
| License string | License string | ||||
| DatasetIDs []int64 // 目前只在StarByMe为true时起作用 | |||||
| DatasetIDs []int64 | |||||
| ListOptions | ListOptions | ||||
| SearchOrderBy | SearchOrderBy | ||||
| IsOwner bool | IsOwner bool | ||||
| @@ -188,6 +190,7 @@ type SearchDatasetOptions struct { | |||||
| JustNeedZipFile bool | JustNeedZipFile bool | ||||
| NeedAttachment bool | NeedAttachment bool | ||||
| UploadAttachmentByMe bool | UploadAttachmentByMe bool | ||||
| QueryReference bool | |||||
| } | } | ||||
| func CreateDataset(dataset *Dataset) (err error) { | func CreateDataset(dataset *Dataset) (err error) { | ||||
| @@ -258,7 +261,7 @@ func SearchDatasetCondition(opts *SearchDatasetOptions) builder.Cond { | |||||
| } | } | ||||
| } | } | ||||
| if len(opts.DatasetIDs) > 0 { | if len(opts.DatasetIDs) > 0 { | ||||
| if opts.StarByMe { | |||||
| if opts.StarByMe || (opts.RepoID == 0 && opts.QueryReference) { | |||||
| cond = cond.And(builder.In("dataset.id", opts.DatasetIDs)) | cond = cond.And(builder.In("dataset.id", opts.DatasetIDs)) | ||||
| } else { | } else { | ||||
| subCon := builder.NewCond() | subCon := builder.NewCond() | ||||
| @@ -329,13 +332,15 @@ func SearchDatasetByCondition(opts *SearchDatasetOptions, cond builder.Cond) (Da | |||||
| return nil, 0, fmt.Errorf("Count: %v", err) | return nil, 0, fmt.Errorf("Count: %v", err) | ||||
| } | } | ||||
| sess.Select(selectColumnsSql).Join("INNER", "repository", "repository.id = dataset.repo_id"). | |||||
| builderQuery := builder.Dialect(setting.Database.Type).Select("id", "title", "status", "category", "description", "download_times", "license", "task", "release_id", "user_id", "repo_id", "created_unix", "updated_unix", "num_stars", "recommend", "use_count").From(builder.Dialect(setting.Database.Type).Select(selectColumnsSql).From("dataset").Join("INNER", "repository", "repository.id = dataset.repo_id"). | |||||
| Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). | Join("INNER", "attachment", "attachment.dataset_id=dataset.id"). | ||||
| Where(cond).OrderBy(opts.SearchOrderBy.String()) | |||||
| Where(cond), "d").OrderBy(opts.SearchOrderBy.String()) | |||||
| if opts.PageSize > 0 { | if opts.PageSize > 0 { | ||||
| sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | |||||
| builderQuery.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize) | |||||
| } | } | ||||
| if err = sess.Find(&datasets); err != nil { | |||||
| if err = sess.SQL(builderQuery).Find(&datasets); err != nil { | |||||
| return nil, 0, fmt.Errorf("Dataset: %v", err) | return nil, 0, fmt.Errorf("Dataset: %v", err) | ||||
| } | } | ||||
| @@ -0,0 +1,88 @@ | |||||
| package models | |||||
| import ( | |||||
| "strconv" | |||||
| "strings" | |||||
| "code.gitea.io/gitea/modules/timeutil" | |||||
| ) | |||||
| type DatasetReference struct { | |||||
| ID int64 `xorm:"pk autoincr"` | |||||
| RepoID int64 `xorm:"INDEX unique"` | |||||
| DatasetID string `xorm:"TEXT"` | |||||
| CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` | |||||
| } | |||||
| func GetDatasetIdsByRepoID(repoID int64) []int64 { | |||||
| var datasets []int64 | |||||
| var datasetIds []string | |||||
| _ = x.Table("dataset_reference").Where("repo_id=?", repoID). | |||||
| Cols("dataset_reference.dataset_id").Find(&datasetIds) | |||||
| if len(datasetIds) > 0 { | |||||
| for _, datasetIdStr := range strings.Split(datasetIds[0], ",") { | |||||
| datasetId, err := strconv.ParseInt(datasetIdStr, 10, 64) | |||||
| if err != nil { | |||||
| continue | |||||
| } | |||||
| datasets = append(datasets, datasetId) | |||||
| } | |||||
| } | |||||
| return datasets | |||||
| } | |||||
| func HasReferenceDataset(repoID int64) bool { | |||||
| var datasetIds []string | |||||
| _ = x.Table("dataset_reference").Where("repo_id=?", repoID). | |||||
| Cols("dataset_reference.dataset_id").Find(&datasetIds) | |||||
| return len(datasetIds) > 0 | |||||
| } | |||||
| func getReferenceDatasetStr(repoID int64) string { | |||||
| var datasetIds []string | |||||
| _ = x.Table("dataset_reference").Where("repo_id=?", repoID). | |||||
| Cols("dataset_reference.dataset_id").Find(&datasetIds) | |||||
| if len(datasetIds) > 0 { | |||||
| return datasetIds[0] | |||||
| } | |||||
| return "" | |||||
| } | |||||
| func DeleteReferenceDatasetIdsByRepoID(repoID int64) error { | |||||
| _, err := x.Exec("delete from dataset_reference where repo_id=?", repoID) | |||||
| return err | |||||
| } | |||||
| func NewDatasetIdsByRepoID(repoID int64, datasetIds []int64) error { | |||||
| if len(datasetIds) == 0 { //关联数据集数组为空 | |||||
| DeleteReferenceDatasetIdsByRepoID(repoID) | |||||
| } | |||||
| var datasetsStrArray []string | |||||
| for _, datasetId := range datasetIds { | |||||
| datasetsStrArray = append(datasetsStrArray, strconv.FormatInt(datasetId, 10)) | |||||
| } | |||||
| newDatasetStr := strings.Join(datasetsStrArray, ",") | |||||
| oldDatasetStr := getReferenceDatasetStr(repoID) | |||||
| if newDatasetStr == oldDatasetStr { //关联数据集无变化,不需要处理 | |||||
| return nil | |||||
| } | |||||
| if oldDatasetStr != "" { //已经存在关联数据集 | |||||
| _, err := x.Exec("update dataset_reference set dataset_id=? where repo_id=?", newDatasetStr, repoID) | |||||
| return err | |||||
| } else { | |||||
| datasetReference := DatasetReference{ | |||||
| DatasetID: newDatasetStr, | |||||
| RepoID: repoID, | |||||
| } | |||||
| _, err := x.Insert(datasetReference) | |||||
| return err | |||||
| } | |||||
| } | |||||
| @@ -146,6 +146,7 @@ func init() { | |||||
| new(SearchRecord), | new(SearchRecord), | ||||
| new(AiModelConvert), | new(AiModelConvert), | ||||
| new(CloudbrainTemp), | new(CloudbrainTemp), | ||||
| new(DatasetReference), | |||||
| ) | ) | ||||
| tablesStatistic = append(tablesStatistic, | tablesStatistic = append(tablesStatistic, | ||||
| @@ -44,3 +44,11 @@ type EditAttachmentForm struct { | |||||
| func (f *EditAttachmentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | func (f *EditAttachmentForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | ||||
| return validate(errs, ctx.Data, f, ctx.Locale) | return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| } | } | ||||
| type ReferenceDatasetForm struct { | |||||
| DatasetID []int64 `binding:"Required"` | |||||
| } | |||||
| func (f *ReferenceDatasetForm) Validate(ctx *macaron.Context, errs binding.Errors) binding.Errors { | |||||
| return validate(errs, ctx.Data, f, ctx.Locale) | |||||
| } | |||||
| @@ -0,0 +1,43 @@ | |||||
| package context | |||||
| import ( | |||||
| "net/http" | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| "gitea.com/macaron/macaron" | |||||
| ) | |||||
| func RequireRepoReaderJson(unitType models.UnitType) macaron.Handler { | |||||
| return func(ctx *Context) { | |||||
| if !ctx.Repo.CanRead(unitType) { | |||||
| if log.IsTrace() { | |||||
| if ctx.IsSigned { | |||||
| log.Trace("Permission Denied: User %-v cannot read %-v in Repo %-v\n"+ | |||||
| "User in Repo has Permissions: %-+v", | |||||
| ctx.User, | |||||
| unitType, | |||||
| ctx.Repo.Repository, | |||||
| ctx.Repo.Permission) | |||||
| } else { | |||||
| log.Trace("Permission Denied: Anonymous user cannot read %-v in Repo %-v\n"+ | |||||
| "Anonymous user in Repo has Permissions: %-+v", | |||||
| unitType, | |||||
| ctx.Repo.Repository, | |||||
| ctx.Repo.Permission) | |||||
| } | |||||
| } | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("error.no_right"))) | |||||
| return | |||||
| } | |||||
| } | |||||
| } | |||||
| func RequireRepoWriterJson(unitType models.UnitType) macaron.Handler { | |||||
| return func(ctx *Context) { | |||||
| if !ctx.Repo.CanWrite(unitType) { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage(ctx.Tr("error.no_right"))) | |||||
| return | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,5 +1,7 @@ | |||||
| package dataset | package dataset | ||||
| import "code.gitea.io/gitea/models" | |||||
| func GetResourceType(cloudbrainType int) string { | func GetResourceType(cloudbrainType int) string { | ||||
| if cloudbrainType == 0 { | if cloudbrainType == 0 { | ||||
| return "CPU/GPU" | return "CPU/GPU" | ||||
| @@ -15,3 +17,19 @@ func GetStatusText(isPrivate bool) string { | |||||
| return "dataset.public" | return "dataset.public" | ||||
| } | } | ||||
| } | } | ||||
| func IsShowDataSetOfCurrentRepo(repoID int64) bool { | |||||
| repo := models.Repository{ | |||||
| ID: repoID, | |||||
| } | |||||
| dataset, _ := models.GetDatasetByRepo(&repo) | |||||
| if dataset != nil { | |||||
| return true | |||||
| } | |||||
| if models.HasReferenceDataset(repoID) { | |||||
| return false | |||||
| } | |||||
| return true | |||||
| } | |||||
| @@ -193,8 +193,9 @@ var ( | |||||
| Wiki: []string{"never"}, | Wiki: []string{"never"}, | ||||
| }, | }, | ||||
| } | } | ||||
| RepoRootPath string | |||||
| ScriptType = "bash" | |||||
| RepoRootPath string | |||||
| RepoMaxReferenceDatasetNum int | |||||
| ScriptType = "bash" | |||||
| ) | ) | ||||
| func newRepository() { | func newRepository() { | ||||
| @@ -210,6 +211,8 @@ func newRepository() { | |||||
| Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool() | Repository.UseCompatSSHURI = sec.Key("USE_COMPAT_SSH_URI").MustBool() | ||||
| Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1) | Repository.MaxCreationLimit = sec.Key("MAX_CREATION_LIMIT").MustInt(-1) | ||||
| RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gitea-repositories")) | RepoRootPath = sec.Key("ROOT").MustString(path.Join(homeDir, "gitea-repositories")) | ||||
| RepoMaxReferenceDatasetNum = sec.Key("MAX_REF_DATASET_NUM").MustInt(20) | |||||
| forcePathSeparator(RepoRootPath) | forcePathSeparator(RepoRootPath) | ||||
| if !filepath.IsAbs(RepoRootPath) { | if !filepath.IsAbs(RepoRootPath) { | ||||
| RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath) | RepoRootPath = filepath.Join(AppWorkPath, RepoRootPath) | ||||
| @@ -97,23 +97,24 @@ func NewFuncMap() []template.FuncMap { | |||||
| "AllowedReactions": func() []string { | "AllowedReactions": func() []string { | ||||
| return setting.UI.Reactions | return setting.UI.Reactions | ||||
| }, | }, | ||||
| "AvatarLink": models.AvatarLink, | |||||
| "Safe": Safe, | |||||
| "SafeJS": SafeJS, | |||||
| "Str2html": Str2html, | |||||
| "subOne": subOne, | |||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "AttachmentResourceType": dataset.GetResourceType, | |||||
| "AttachmentStatus": dataset.GetStatusText, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "FileSize": base.FileSize, | |||||
| "PrettyNumber": base.PrettyNumber, | |||||
| "Subtract": base.Subtract, | |||||
| "EntryIcon": base.EntryIcon, | |||||
| "MigrationIcon": MigrationIcon, | |||||
| "AvatarLink": models.AvatarLink, | |||||
| "Safe": Safe, | |||||
| "SafeJS": SafeJS, | |||||
| "Str2html": Str2html, | |||||
| "subOne": subOne, | |||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "AttachmentResourceType": dataset.GetResourceType, | |||||
| "AttachmentStatus": dataset.GetStatusText, | |||||
| "IsShowDataSetOfCurrentRepo": dataset.IsShowDataSetOfCurrentRepo, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "FileSize": base.FileSize, | |||||
| "PrettyNumber": base.PrettyNumber, | |||||
| "Subtract": base.Subtract, | |||||
| "EntryIcon": base.EntryIcon, | |||||
| "MigrationIcon": MigrationIcon, | |||||
| "Add": func(a, b int) int { | "Add": func(a, b int) int { | ||||
| return a + b | return a + b | ||||
| }, | }, | ||||
| @@ -357,13 +358,15 @@ func NewTextFuncMap() []texttmpl.FuncMap { | |||||
| "AppDomain": func() string { | "AppDomain": func() string { | ||||
| return setting.Domain | return setting.Domain | ||||
| }, | }, | ||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "AttachmentResourceType": dataset.GetResourceType, | |||||
| "AttachmentStatus": dataset.GetStatusText, | |||||
| "TimeSince": timeutil.TimeSince, | |||||
| "TimeSinceUnix": timeutil.TimeSinceUnix, | |||||
| "TimeSinceUnix1": timeutil.TimeSinceUnix1, | |||||
| "TimeSinceUnixShort": timeutil.TimeSinceUnixShort, | |||||
| "RawTimeSince": timeutil.RawTimeSince, | |||||
| "AttachmentResourceType": dataset.GetResourceType, | |||||
| "AttachmentStatus": dataset.GetStatusText, | |||||
| "IsShowDataSetOfCurrentRepo": dataset.IsShowDataSetOfCurrentRepo, | |||||
| "DateFmtLong": func(t time.Time) string { | "DateFmtLong": func(t time.Time) string { | ||||
| return t.Format(time.RFC1123Z) | return t.Format(time.RFC1123Z) | ||||
| }, | }, | ||||
| @@ -98,6 +98,7 @@ error500= Sorry, the site has encountered some problems, we are trying to <stron | |||||
| [error] | [error] | ||||
| occurred = An error has occurred | occurred = An error has occurred | ||||
| report_message = An error has occurred | report_message = An error has occurred | ||||
| no_right=You have no right to do the operation. | |||||
| [install] | [install] | ||||
| install = Installation | install = Installation | ||||
| @@ -837,6 +838,8 @@ category = Category | |||||
| no_category = No Category | no_category = No Category | ||||
| task = Task | task = Task | ||||
| no_task = No Task | no_task = No Task | ||||
| reference_dataset_fail=Failed to reference dataset, please try again later. | |||||
| cancel_reference_dataset_fail=Failed to cancel reference dataset, please try again later. | |||||
| license = License | license = License | ||||
| no_license = No License | no_license = No License | ||||
| file = Dataset File | file = Dataset File | ||||
| @@ -949,6 +952,11 @@ unzip_failed=Unzip Failed | |||||
| unzip_stared=Unzipping | unzip_stared=Unzipping | ||||
| unzip_status=Unzip Status | unzip_status=Unzip Status | ||||
| collection_num=Collection Nums | collection_num=Collection Nums | ||||
| current_dataset=Current Dataset | |||||
| linked_dataset=Linked Dataset | |||||
| unfavorite=Unfavorite | |||||
| favorite=Favorite | |||||
| disassociate=Disassociate | |||||
| [repo] | [repo] | ||||
| owner = Owner | owner = Owner | ||||
| repo_name = Repository Name | repo_name = Repository Name | ||||
| @@ -99,6 +99,7 @@ error500=抱歉,站点遇到一些问题,我们正尝试<strong>修复网页 | |||||
| [error] | [error] | ||||
| occurred=发生错误 | occurred=发生错误 | ||||
| report_message=发生错误 | report_message=发生错误 | ||||
| no_right=您没有权限执行本操作。 | |||||
| [install] | [install] | ||||
| install=安装页面 | install=安装页面 | ||||
| @@ -832,6 +833,10 @@ create_dataset=创建数据集 | |||||
| create_dataset_fail=创建数据集失败。 | create_dataset_fail=创建数据集失败。 | ||||
| query_dataset_fail=查询数据集失败。 | query_dataset_fail=查询数据集失败。 | ||||
| edit_attachment_fail=修改描述失败。 | edit_attachment_fail=修改描述失败。 | ||||
| reference_dataset_fail=关联数据集失败,请稍后再试。 | |||||
| cancel_reference_dataset_fail=取消关联数据集失败,请稍后再试。 | |||||
| download_url=数据集下载地址 | download_url=数据集下载地址 | ||||
| download_copy=复制链接 | download_copy=复制链接 | ||||
| download_oper=操作 | download_oper=操作 | ||||
| @@ -953,6 +958,12 @@ unzip_failed=解压失败 | |||||
| unzip_stared=解压中 | unzip_stared=解压中 | ||||
| unzip_status=解压状态 | unzip_status=解压状态 | ||||
| collection_num=收藏数量 | collection_num=收藏数量 | ||||
| current_dataset=当前数据集 | |||||
| linked_dataset=关联数据集 | |||||
| unfavorite=取消收藏 | |||||
| favorite=收藏 | |||||
| disassociate=取消关联 | |||||
| [repo] | [repo] | ||||
| owner=拥有者 | owner=拥有者 | ||||
| repo_name=项目名称 | repo_name=项目名称 | ||||
| @@ -764,7 +764,7 @@ func GetCloudbrainsDetailData(ctx *context.Context) { | |||||
| taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain) | taskDetail.WaitTime = repo.GetCloudbrainWaitTime(ciTasks[i].Cloudbrain) | ||||
| if ciTasks[i].Cloudbrain.DeletedAt != nilTime { | |||||
| if ciTasks[i].Cloudbrain.DeletedAt != nilTime || ciTasks[i].Repo == nil { | |||||
| taskDetail.IsDelete = true | taskDetail.IsDelete = true | ||||
| } else { | } else { | ||||
| taskDetail.IsDelete = false | taskDetail.IsDelete = false | ||||
| @@ -296,11 +296,10 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| // ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled | // ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled | ||||
| var ( | var ( | ||||
| datasets []*models.Dataset | |||||
| datasetsWithStar []*models.DatasetWithStar | |||||
| count int64 | |||||
| err error | |||||
| orderBy models.SearchOrderBy | |||||
| datasets []*models.Dataset | |||||
| count int64 | |||||
| err error | |||||
| orderBy models.SearchOrderBy | |||||
| ) | ) | ||||
| page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
| if page <= 0 { | if page <= 0 { | ||||
| @@ -379,14 +378,6 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| ctx.ServerError("SearchDatasets", err) | ctx.ServerError("SearchDatasets", err) | ||||
| return | return | ||||
| } | } | ||||
| for _, dataset := range datasets { | |||||
| if !ctx.IsSigned { | |||||
| datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: false}) | |||||
| } else { | |||||
| datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: models.IsDatasetStaring(ctx.User.ID, dataset.ID)}) | |||||
| } | |||||
| } | |||||
| pager := context.NewPagination(int(count), opts.PageSize, page, 5) | pager := context.NewPagination(int(count), opts.PageSize, page, 5) | ||||
| ctx.Data["Keyword"] = opts.Keyword | ctx.Data["Keyword"] = opts.Keyword | ||||
| @@ -397,7 +388,7 @@ func ExploreDatasets(ctx *context.Context) { | |||||
| pager.SetDefaultParams(ctx) | pager.SetDefaultParams(ctx) | ||||
| ctx.Data["Page"] = pager | ctx.Data["Page"] = pager | ||||
| ctx.Data["Datasets"] = datasetsWithStar | |||||
| ctx.Data["Datasets"] = repository.ConvertToDatasetWithStar(ctx, datasets) | |||||
| ctx.Data["Total"] = count | ctx.Data["Total"] = count | ||||
| ctx.Data["PageIsDatasets"] = true | ctx.Data["PageIsDatasets"] = true | ||||
| ctx.HTML(200, tplExploreDataset) | ctx.HTML(200, tplExploreDataset) | ||||
| @@ -9,6 +9,8 @@ import ( | |||||
| "strings" | "strings" | ||||
| "unicode/utf8" | "unicode/utf8" | ||||
| "code.gitea.io/gitea/services/repository" | |||||
| "code.gitea.io/gitea/models" | "code.gitea.io/gitea/models" | ||||
| "code.gitea.io/gitea/modules/auth" | "code.gitea.io/gitea/modules/auth" | ||||
| "code.gitea.io/gitea/modules/base" | "code.gitea.io/gitea/modules/base" | ||||
| @@ -22,6 +24,7 @@ const ( | |||||
| tplDatasetCreate base.TplName = "repo/datasets/create" | tplDatasetCreate base.TplName = "repo/datasets/create" | ||||
| tplDatasetEdit base.TplName = "repo/datasets/edit" | tplDatasetEdit base.TplName = "repo/datasets/edit" | ||||
| taskstplIndex base.TplName = "repo/datasets/tasks/index" | taskstplIndex base.TplName = "repo/datasets/tasks/index" | ||||
| tplReference base.TplName = "repo/datasets/reference" | |||||
| ) | ) | ||||
| // MustEnableDataset check if repository enable internal dataset | // MustEnableDataset check if repository enable internal dataset | ||||
| @@ -266,6 +269,37 @@ func CreateDatasetPost(ctx *context.Context, form auth.CreateDatasetForm) { | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | ctx.JSON(http.StatusOK, models.BaseOKMessage) | ||||
| } | } | ||||
| } | |||||
| func ReferenceDatasetDelete(ctx *context.Context) { | |||||
| repoID := ctx.Repo.Repository.ID | |||||
| datasetId, _ := strconv.ParseInt(ctx.Params(":id"), 10, 64) | |||||
| oldDatasetIds := models.GetDatasetIdsByRepoID(repoID) | |||||
| var newDatasetIds []int64 | |||||
| for _, tempDatasetId := range oldDatasetIds { | |||||
| if datasetId != tempDatasetId { | |||||
| newDatasetIds = append(newDatasetIds, tempDatasetId) | |||||
| } | |||||
| } | |||||
| err := models.NewDatasetIdsByRepoID(repoID, newDatasetIds) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage("dataset.cancel_reference_dataset_fail")) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||||
| } | |||||
| func ReferenceDatasetPost(ctx *context.Context, form auth.ReferenceDatasetForm) { | |||||
| repoID := ctx.Repo.Repository.ID | |||||
| err := models.NewDatasetIdsByRepoID(repoID, form.DatasetID) | |||||
| if err != nil { | |||||
| ctx.JSON(http.StatusOK, models.BaseErrorMessage("dataset.reference_dataset_fail")) | |||||
| } | |||||
| ctx.JSON(http.StatusOK, models.BaseOKMessage) | |||||
| } | } | ||||
| func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | func EditDatasetPost(ctx *context.Context, form auth.EditDatasetForm) { | ||||
| @@ -412,18 +446,17 @@ func MyDatasets(ctx *context.Context) { | |||||
| func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) { | func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) { | ||||
| page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
| cloudbrainType := ctx.QueryInt("type") | |||||
| keyword := strings.Trim(ctx.Query("q"), " ") | keyword := strings.Trim(ctx.Query("q"), " ") | ||||
| orderBy := models.SearchOrderByRecentUpdated | |||||
| opts.Keyword = keyword | opts.Keyword = keyword | ||||
| opts.SearchOrderBy = orderBy | |||||
| if opts.SearchOrderBy.String() == "" { | |||||
| opts.SearchOrderBy = models.SearchOrderByRecentUpdated | |||||
| } | |||||
| opts.RecommendOnly = ctx.QueryBool("recommend") | opts.RecommendOnly = ctx.QueryBool("recommend") | ||||
| opts.CloudBrainType = cloudbrainType | |||||
| opts.ListOptions = models.ListOptions{ | opts.ListOptions = models.ListOptions{ | ||||
| Page: page, | Page: page, | ||||
| PageSize: setting.UI.DatasetPagingNum, | PageSize: setting.UI.DatasetPagingNum, | ||||
| } | } | ||||
| opts.NeedAttachment = true | |||||
| opts.JustNeedZipFile = true | opts.JustNeedZipFile = true | ||||
| opts.User = ctx.User | opts.User = ctx.User | ||||
| @@ -449,22 +482,52 @@ func datasetMultiple(ctx *context.Context, opts *models.SearchDatasetOptions) { | |||||
| "data": string(data), | "data": string(data), | ||||
| "count": strconv.FormatInt(count, 10), | "count": strconv.FormatInt(count, 10), | ||||
| }) | }) | ||||
| } | } | ||||
| func CurrentRepoDatasetMultiple(ctx *context.Context) { | func CurrentRepoDatasetMultiple(ctx *context.Context) { | ||||
| datasetIds := models.GetDatasetIdsByRepoID(ctx.Repo.Repository.ID) | |||||
| searchOrderBy := getSearchOrderByInValues(datasetIds) | |||||
| opts := &models.SearchDatasetOptions{ | opts := &models.SearchDatasetOptions{ | ||||
| RepoID: ctx.Repo.Repository.ID, | |||||
| RepoID: ctx.Repo.Repository.ID, | |||||
| NeedAttachment: true, | |||||
| CloudBrainType: ctx.QueryInt("type"), | |||||
| DatasetIDs: datasetIds, | |||||
| SearchOrderBy: searchOrderBy, | |||||
| } | } | ||||
| datasetMultiple(ctx, opts) | datasetMultiple(ctx, opts) | ||||
| } | } | ||||
| func getSearchOrderByInValues(datasetIds []int64) models.SearchOrderBy { | |||||
| if len(datasetIds) == 0 { | |||||
| return "" | |||||
| } | |||||
| searchOrderBy := "CASE id " | |||||
| for i, id := range datasetIds { | |||||
| searchOrderBy += fmt.Sprintf(" WHEN %d THEN %d", id, i+1) | |||||
| } | |||||
| searchOrderBy += " ELSE 0 END" | |||||
| return models.SearchOrderBy(searchOrderBy) | |||||
| } | |||||
| func MyDatasetsMultiple(ctx *context.Context) { | func MyDatasetsMultiple(ctx *context.Context) { | ||||
| opts := &models.SearchDatasetOptions{ | opts := &models.SearchDatasetOptions{ | ||||
| UploadAttachmentByMe: true, | UploadAttachmentByMe: true, | ||||
| NeedAttachment: true, | |||||
| CloudBrainType: ctx.QueryInt("type"), | |||||
| } | |||||
| datasetMultiple(ctx, opts) | |||||
| } | |||||
| func ReferenceDatasetAvailable(ctx *context.Context) { | |||||
| opts := &models.SearchDatasetOptions{ | |||||
| PublicOnly: true, | |||||
| NeedAttachment: false, | |||||
| CloudBrainType: models.TypeCloudBrainAll, | |||||
| } | } | ||||
| datasetMultiple(ctx, opts) | datasetMultiple(ctx, opts) | ||||
| @@ -473,7 +536,9 @@ func MyDatasetsMultiple(ctx *context.Context) { | |||||
| func PublicDatasetMultiple(ctx *context.Context) { | func PublicDatasetMultiple(ctx *context.Context) { | ||||
| opts := &models.SearchDatasetOptions{ | opts := &models.SearchDatasetOptions{ | ||||
| PublicOnly: true, | |||||
| PublicOnly: true, | |||||
| NeedAttachment: true, | |||||
| CloudBrainType: ctx.QueryInt("type"), | |||||
| } | } | ||||
| datasetMultiple(ctx, opts) | datasetMultiple(ctx, opts) | ||||
| @@ -482,11 +547,50 @@ func PublicDatasetMultiple(ctx *context.Context) { | |||||
| func MyFavoriteDatasetMultiple(ctx *context.Context) { | func MyFavoriteDatasetMultiple(ctx *context.Context) { | ||||
| opts := &models.SearchDatasetOptions{ | opts := &models.SearchDatasetOptions{ | ||||
| StarByMe: true, | |||||
| DatasetIDs: models.GetDatasetIdsStarByUser(ctx.User.ID), | |||||
| StarByMe: true, | |||||
| DatasetIDs: models.GetDatasetIdsStarByUser(ctx.User.ID), | |||||
| NeedAttachment: true, | |||||
| CloudBrainType: ctx.QueryInt("type"), | |||||
| } | } | ||||
| datasetMultiple(ctx, opts) | datasetMultiple(ctx, opts) | ||||
| } | } | ||||
| func ReferenceDataset(ctx *context.Context) { | |||||
| MustEnableDataset(ctx) | |||||
| ctx.Data["PageIsDataset"] = true | |||||
| ctx.Data["MaxReferenceDatasetNum"] = setting.RepoMaxReferenceDatasetNum | |||||
| ctx.Data["CanWrite"] = ctx.Repo.CanWrite(models.UnitTypeDatasets) | |||||
| ctx.HTML(200, tplReference) | |||||
| } | |||||
| func ReferenceDatasetData(ctx *context.Context) { | |||||
| MustEnableDataset(ctx) | |||||
| datasetIds := models.GetDatasetIdsByRepoID(ctx.Repo.Repository.ID) | |||||
| var datasets models.DatasetList | |||||
| var err error | |||||
| if len(datasetIds) > 0 { | |||||
| opts := &models.SearchDatasetOptions{ | |||||
| DatasetIDs: datasetIds, | |||||
| NeedAttachment: false, | |||||
| CloudBrainType: models.TypeCloudBrainAll, | |||||
| ListOptions: models.ListOptions{ | |||||
| Page: 1, | |||||
| PageSize: setting.RepoMaxReferenceDatasetNum, | |||||
| }, | |||||
| SearchOrderBy: getSearchOrderByInValues(datasetIds), | |||||
| QueryReference: true, | |||||
| } | |||||
| datasets, _, err = models.SearchDataset(opts) | |||||
| if err != nil { | |||||
| ctx.ServerError("SearchDatasets", err) | |||||
| return | |||||
| } | |||||
| } | |||||
| ctx.JSON(http.StatusOK, repository.ConvertToDatasetWithStar(ctx, datasets)) | |||||
| } | |||||
| func PublicDataset(ctx *context.Context) { | func PublicDataset(ctx *context.Context) { | ||||
| page := ctx.QueryInt("page") | page := ctx.QueryInt("page") | ||||
| @@ -676,6 +676,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| reqRepoIssuesOrPullsReader := context.RequireRepoReaderOr(models.UnitTypeIssues, models.UnitTypePullRequests) | reqRepoIssuesOrPullsReader := context.RequireRepoReaderOr(models.UnitTypeIssues, models.UnitTypePullRequests) | ||||
| reqRepoDatasetReader := context.RequireRepoReader(models.UnitTypeDatasets) | reqRepoDatasetReader := context.RequireRepoReader(models.UnitTypeDatasets) | ||||
| reqRepoDatasetWriter := context.RequireRepoWriter(models.UnitTypeDatasets) | reqRepoDatasetWriter := context.RequireRepoWriter(models.UnitTypeDatasets) | ||||
| reqRepoDatasetReaderJson := context.RequireRepoReaderJson(models.UnitTypeDatasets) | |||||
| reqRepoDatasetWriterJson := context.RequireRepoWriterJson(models.UnitTypeDatasets) | |||||
| reqRepoCloudBrainReader := context.RequireRepoReader(models.UnitTypeCloudBrain) | reqRepoCloudBrainReader := context.RequireRepoReader(models.UnitTypeCloudBrain) | ||||
| reqRepoCloudBrainWriter := context.RequireRepoWriter(models.UnitTypeCloudBrain) | reqRepoCloudBrainWriter := context.RequireRepoWriter(models.UnitTypeCloudBrain) | ||||
| reqRepoModelManageReader := context.RequireRepoReader(models.UnitTypeModelManage) | reqRepoModelManageReader := context.RequireRepoReader(models.UnitTypeModelManage) | ||||
| @@ -1032,10 +1035,14 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("/datasets", func() { | m.Group("/datasets", func() { | ||||
| m.Get("", reqRepoDatasetReader, repo.DatasetIndex) | m.Get("", reqRepoDatasetReader, repo.DatasetIndex) | ||||
| m.Get("/reference_datasets", reqRepoDatasetReader, repo.ReferenceDataset) | |||||
| m.Get("/reference_datasets_data", reqRepoDatasetReaderJson, repo.ReferenceDatasetData) | |||||
| m.Delete("/reference_datasets/:id", reqRepoDatasetWriterJson, repo.ReferenceDatasetDelete) | |||||
| m.Put("/:id/:action", reqRepoDatasetReader, repo.DatasetAction) | m.Put("/:id/:action", reqRepoDatasetReader, repo.DatasetAction) | ||||
| m.Get("/create", reqRepoDatasetWriter, repo.CreateDataset) | m.Get("/create", reqRepoDatasetWriter, repo.CreateDataset) | ||||
| m.Post("/create", reqRepoDatasetWriter, bindIgnErr(auth.CreateDatasetForm{}), repo.CreateDatasetPost) | m.Post("/create", reqRepoDatasetWriter, bindIgnErr(auth.CreateDatasetForm{}), repo.CreateDatasetPost) | ||||
| m.Get("/edit/:id", reqRepoDatasetWriter, repo.EditDataset) | m.Get("/edit/:id", reqRepoDatasetWriter, repo.EditDataset) | ||||
| m.Post("/reference_datasets", reqRepoDatasetWriterJson, bindIgnErr(auth.ReferenceDatasetForm{}), repo.ReferenceDatasetPost) | |||||
| m.Post("/edit", reqRepoDatasetWriter, bindIgnErr(auth.EditDatasetForm{}), repo.EditDatasetPost) | m.Post("/edit", reqRepoDatasetWriter, bindIgnErr(auth.EditDatasetForm{}), repo.EditDatasetPost) | ||||
| m.Get("/current_repo", repo.CurrentRepoDataset) | m.Get("/current_repo", repo.CurrentRepoDataset) | ||||
| m.Get("/my_datasets", repo.MyDatasets) | m.Get("/my_datasets", repo.MyDatasets) | ||||
| @@ -1045,6 +1052,8 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Get("/current_repo_m", repo.CurrentRepoDatasetMultiple) | m.Get("/current_repo_m", repo.CurrentRepoDatasetMultiple) | ||||
| m.Get("/my_datasets_m", repo.MyDatasetsMultiple) | m.Get("/my_datasets_m", repo.MyDatasetsMultiple) | ||||
| m.Get("/public_datasets_m", repo.PublicDatasetMultiple) | m.Get("/public_datasets_m", repo.PublicDatasetMultiple) | ||||
| m.Get("/reference_datasets_available", repo.ReferenceDatasetAvailable) | |||||
| m.Get("/my_favorite_m", repo.MyFavoriteDatasetMultiple) | m.Get("/my_favorite_m", repo.MyFavoriteDatasetMultiple) | ||||
| m.Group("/status", func() { | m.Group("/status", func() { | ||||
| @@ -0,0 +1,19 @@ | |||||
| package repository | |||||
| import ( | |||||
| "code.gitea.io/gitea/models" | |||||
| "code.gitea.io/gitea/modules/context" | |||||
| ) | |||||
| func ConvertToDatasetWithStar(ctx *context.Context, datasets []*models.Dataset) []*models.DatasetWithStar { | |||||
| var datasetsWithStar []*models.DatasetWithStar | |||||
| for _, dataset := range datasets { | |||||
| if !ctx.IsSigned { | |||||
| datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: false}) | |||||
| } else { | |||||
| datasetsWithStar = append(datasetsWithStar, &models.DatasetWithStar{Dataset: *dataset, IsStaring: models.IsDatasetStaring(ctx.User.ID, dataset.ID)}) | |||||
| } | |||||
| } | |||||
| return datasetsWithStar | |||||
| } | |||||
| @@ -20,7 +20,6 @@ | |||||
| .wrapper { | .wrapper { | ||||
| display: flex; | display: flex; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| padding: 0 1rem; | |||||
| } | } | ||||
| .exp { | .exp { | ||||
| @@ -40,7 +39,8 @@ | |||||
| } | } | ||||
| .exp:checked+.text .btn::after { | .exp:checked+.text .btn::after { | ||||
| content:'{{$.i18n.Tr "org.fold"}}' | |||||
| content:'{{$.i18n.Tr "org.fold"}}'; | |||||
| color: #3291f8; | |||||
| } | } | ||||
| .wrapper>.text { | .wrapper>.text { | ||||
| @@ -80,7 +80,7 @@ | |||||
| margin-left: 20px; | margin-left: 20px; | ||||
| font-size: 14px; | font-size: 14px; | ||||
| padding: 0 8px; | padding: 0 8px; | ||||
| background: #3F51B5; | |||||
| background-color: transparent; | |||||
| line-height: 20px; | line-height: 20px; | ||||
| border-radius: 4px; | border-radius: 4px; | ||||
| color: #fff; | color: #fff; | ||||
| @@ -89,7 +89,8 @@ | |||||
| } | } | ||||
| .btn::after { | .btn::after { | ||||
| content:'{{$.i18n.Tr "org.unfold"}}' | |||||
| content:'{{$.i18n.Tr "org.unfold"}}'; | |||||
| color: #3291f8; | |||||
| } | } | ||||
| .btn::before { | .btn::before { | ||||
| @@ -132,6 +133,15 @@ | |||||
| border: 5px solid transparent; | border: 5px solid transparent; | ||||
| border-top-color: #c0c4cc; | border-top-color: #c0c4cc; | ||||
| } | } | ||||
| .dataset-flavor-button{ | |||||
| display: flex; | |||||
| align-items: center; | |||||
| padding: 0.5rem; | |||||
| border: 1px solid rgba(34,36,38,0.15); | |||||
| border-top-right-radius: 0; | |||||
| border-bottom-right-radius: 0; | |||||
| box-shadow: none | |||||
| } | |||||
| </style> | </style> | ||||
| <div class="repository"> | <div class="repository"> | ||||
| {{template "repo/header" .}} | {{template "repo/header" .}} | ||||
| @@ -142,44 +152,59 @@ | |||||
| <div class="item" data-private="{{.IsPrivate}}" data-decompress-state="{{.DecompressState}}"></div> | <div class="item" data-private="{{.IsPrivate}}" data-decompress-state="{{.DecompressState}}"></div> | ||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| <div id="dataset-base"> | <div id="dataset-base"> | ||||
| <div class="ui container"> | <div class="ui container"> | ||||
| <div class="ui mobile reversed stackable grid"> | <div class="ui mobile reversed stackable grid"> | ||||
| <div class="row"> | <div class="row"> | ||||
| <div class="column thirteen wide"> | |||||
| <h2 class="nowrap">{{.dataset.Title}}</h2> | |||||
| <div class="ui blue small menu compact selectcloudbrain"> | |||||
| <a class="active item" href="{{.RepoLink}}/datasets">{{$.i18n.Tr "dataset.current_dataset"}}</a> | |||||
| <a class="item" href="{{.RepoLink}}/datasets/reference_datasets">{{$.i18n.Tr "dataset.linked_dataset"}}</a> | |||||
| </div> | </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> | |||||
| </div> | |||||
| <div class="row" style="align-items: center;"> | |||||
| <h2 class="nowrap" style="margin: 0;">{{.dataset.Title}}</h2> | |||||
| <!-- border-top-right-radius: 0; | |||||
| border-bottom-right-radius: 0; --> | |||||
| <div style="margin-left: 1.5rem;"> | |||||
| {{if $.IsSigned}} | |||||
| <button v-if="star_active" class="ui mini basic button" style="display: flex;align-items: center;padding: 0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;" @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||||
| <i class="ri-heart-fill" style="color: #FA8C16;"></i> | |||||
| <span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.unfavorite"}}</span> | |||||
| </button> | |||||
| <button v-else class="ui mini basic button" style="display: flex;align-items: center;padding:0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;" @click="postStar({{.dataset.ID}},'{{.Link}}')"> | |||||
| <i class="ri-heart-line" ></i> | |||||
| <span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.favorite"}}</span> | |||||
| </button> | |||||
| {{else}} | |||||
| <button v-if="star_active" class="ui mini basic button" style="display: flex;align-items: center;padding: 0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;"> | |||||
| <i class="ri-heart-fill" ></i> | |||||
| <span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.unfavorite"}}</span> | |||||
| </button> | |||||
| <button v-else class="ui mini basic button" style="display: flex;align-items: center;padding:0.5rem;border: #888888;border-top-right-radius: 0;border-bottom-right-radius: 0;margin-right: -1px;"> | |||||
| <i class="ri-heart-line" style="color: #FA8C16;"></i> | |||||
| <span style="margin-left: 0.3rem;font-size: 0.7rem;">{{$.i18n.Tr "dataset.favorite"}}</span> | |||||
| </button> | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| <a class="ui mini basic button" style="display: flex;align-items: center;padding: 0.5rem;border: #888888;border-top-left-radius: 0;border-bottom-left-radius: 0;"> | |||||
| ${num_stars} | |||||
| </a> | |||||
| <a style="margin-left:15px;padding: 0.5rem 1.5rem;" href="{{.RepoLink}}/datasets/edit/{{.dataset.ID}}" class="ui primary basic mini {{if not $.CanWrite}} disabled {{end}} button">{{.i18n.Tr "repo.modelarts.modify"}}</a> | |||||
| </div> | |||||
| {{if .dataset.Description}} | |||||
| <div class="row" style="padding: 0;"> | |||||
| <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" style="align-items: center;"> | |||||
| {{if or (.dataset.Category) (.dataset.Task) (.dataset.License)}} | {{if or (.dataset.Category) (.dataset.Task) (.dataset.License)}} | ||||
| <div class="column thirteen wide"> | |||||
| <div class="column ten wide" style="padding:0"> | |||||
| {{if .dataset.Category}} | {{if .dataset.Category}} | ||||
| {{$category := .dataset.Category}} | {{$category := .dataset.Category}} | ||||
| <a class="ui repo-topic label topic" | <a class="ui repo-topic label topic" | ||||
| @@ -196,21 +221,7 @@ | |||||
| {{end}} | {{end}} | ||||
| </div> | </div> | ||||
| {{end}} | {{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> | |||||
| </div> | |||||
| {{end}} | |||||
| <div class="row"> | |||||
| <div class="column ten wide"></div> | |||||
| <div class="column six wide right aligned"> | |||||
| <div class="column six wide right aligned" style="padding:0"> | |||||
| <el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType"> | <el-select v-model="datasetType" style="width: 40%;" size="small" @change="changeDatasetType"> | ||||
| <i slot="prefix" style="display: inline-block;color: #101010;" | <i slot="prefix" style="display: inline-block;color: #101010;" | ||||
| class="el-input__icon ri-archive-drawer-line"></i> | class="el-input__icon ri-archive-drawer-line"></i> | ||||
| @@ -222,7 +233,7 @@ | |||||
| @click="gotoUpload('{{.RepoLink}}',{{.dataset.ID}})">{{$.i18n.Tr "dataset.dataset_upload"}}</el-button> | @click="gotoUpload('{{.RepoLink}}',{{.dataset.ID}})">{{$.i18n.Tr "dataset.dataset_upload"}}</el-button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="row"> | |||||
| <div class="row" style="padding-top: 0;"> | |||||
| <div class="ui sixteen wide column dataset"> | <div class="ui sixteen wide column dataset"> | ||||
| <div class="ui grid stackable" style="background: #f0f0f0;;"> | <div class="ui grid stackable" style="background: #f0f0f0;;"> | ||||
| <div class="row"> | <div class="row"> | ||||
| @@ -387,16 +398,27 @@ | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| {{else}} | {{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 class="ui container"> | |||||
| <div class="ui stackable grid"> | |||||
| <div class="row" style="justify-content: space-between"> | |||||
| <div class="ui blue small menu compact selectcloudbrain"> | |||||
| <a class="active item" href="{{.RepoLink}}/datasets">{{$.i18n.Tr "dataset.current_dataset"}}</a> | |||||
| <a class="item" href="{{.RepoLink}}/datasets/reference_datasets">{{$.i18n.Tr "dataset.linked_dataset"}}</a> | |||||
| </div> | |||||
| {{if $.CanWrite}} | |||||
| <a class="ui green button" href="{{.RepoLink}}/datasets/create">{{$.i18n.Tr "dataset.new_dataset"}}</a> | |||||
| {{end}} | |||||
| </div> | |||||
| </div> | |||||
| <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> | |||||
| <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> | </div> | ||||
| </div> | </div> | ||||
| {{end}} | {{end}} | ||||
| @@ -0,0 +1,8 @@ | |||||
| {{template "base/head" .}} | |||||
| <div class="repository"> | |||||
| {{template "repo/header" .}} | |||||
| <div class="reference-dataset" data-repolink="{{.RepoLink}}" data-canwrite="{{.CanWrite}}" data-is-sign="{{$.IsSigned}}" data-max-reference-num="{{.MaxReferenceDatasetNum}}" data-address="{{IsShowDataSetOfCurrentRepo $.Repository.ID}}"></div> | |||||
| <div id="reference-dataset"></div> | |||||
| </div> | |||||
| {{template "base/footer" .}} | |||||
| @@ -138,7 +138,7 @@ | |||||
| {{end}} | {{end}} | ||||
| {{if .Permission.CanRead $.UnitTypeDatasets}} | {{if .Permission.CanRead $.UnitTypeDatasets}} | ||||
| <a class="{{if .PageIsDataset}}active{{end}} item" href="{{.RepoLink}}/datasets"> | |||||
| <a class="{{if .PageIsDataset}}active{{end}} item" id="header-dataset" href="{{.RepoLink}}{{if IsShowDataSetOfCurrentRepo $.Repository.ID}}/datasets{{else}}/datasets/reference_datasets{{end}}"> | |||||
| <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="M20.083 15.2l1.202.721a.5.5 0 0 1 0 .858l-8.77 5.262a1 1 0 0 1-1.03 0l-8.77-5.262a.5.5 0 0 1 0-.858l1.202-.721L12 20.05l8.083-4.85zm0-4.7l1.202.721a.5.5 0 0 1 0 .858L12 17.65l-9.285-5.571a.5.5 0 0 1 0-.858l1.202-.721L12 15.35l8.083-4.85zm-7.569-9.191l8.771 5.262a.5.5 0 0 1 0 .858L12 13 2.715 7.429a.5.5 0 0 1 0-.858l8.77-5.262a1 1 0 0 1 1.03 0zM12 3.332L5.887 7 12 10.668 18.113 7 12 3.332z"/></svg> | <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="M20.083 15.2l1.202.721a.5.5 0 0 1 0 .858l-8.77 5.262a1 1 0 0 1-1.03 0l-8.77-5.262a.5.5 0 0 1 0-.858l1.202-.721L12 20.05l8.083-4.85zm0-4.7l1.202.721a.5.5 0 0 1 0 .858L12 17.65l-9.285-5.571a.5.5 0 0 1 0-.858l1.202-.721L12 15.35l8.083-4.85zm-7.569-9.191l8.771 5.262a.5.5 0 0 1 0 .858L12 13 2.715 7.429a.5.5 0 0 1 0-.858l8.77-5.262a1 1 0 0 1 1.03 0zM12 3.332L5.887 7 12 10.668 18.113 7 12 3.332z"/></svg> | ||||
| {{.i18n.Tr "datasets"}} | {{.i18n.Tr "datasets"}} | ||||
| </a> | </a> | ||||
| @@ -0,0 +1,735 @@ | |||||
| <template> | |||||
| <div> | |||||
| <template v-if="showFlag"> | |||||
| <div v-loading="loadingLinkPage"> | |||||
| <div class="ui container"> | |||||
| <div class="ui mobile reversed stackable grid"> | |||||
| <div class="row" style="justify-content: space-between"> | |||||
| <div class="ui blue small menu compact selectcloudbrain"> | |||||
| <a class="item" :href="`${repoLink}/datasets`">{{ | |||||
| i18n.current_dataset | |||||
| }}</a> | |||||
| <a | |||||
| class="active item" | |||||
| :href="`${repoLink}/datasets/reference_datasets`" | |||||
| >{{ i18n.linked_datasets }}</a | |||||
| > | |||||
| </div> | |||||
| <button | |||||
| style="margin-right: 2rem" | |||||
| class="ui green button" | |||||
| :class="{ disabled: !canWrite }" | |||||
| @click="openDataset()" | |||||
| > | |||||
| {{ i18n.linked_datasets }} | |||||
| </button> | |||||
| </div> | |||||
| <div class="row"> | |||||
| <div class="ui two cards" style="width: 100%"> | |||||
| <div | |||||
| class="ui card refer-dataset-card" | |||||
| v-for="(item, index) in datasetList" | |||||
| :key="index" | |||||
| @click="gotoDataset(item)" | |||||
| > | |||||
| <div class="content" style="border-bottom: none"> | |||||
| <div class="refer-dataset-card-content"> | |||||
| <div class="refer-dataset-card-title"> | |||||
| <span | |||||
| :title="item.Title" | |||||
| class="nowrap" | |||||
| style="display: inline-block; max-width: 90%" | |||||
| >{{ item.Title }}</span | |||||
| ><img | |||||
| v-if="item.Recommend" | |||||
| src="/img/jian.svg" | |||||
| style="margin-left: 0.5rem" | |||||
| /> | |||||
| </div> | |||||
| <template v-if="item.IsStaring"> | |||||
| <div style="display: flex"> | |||||
| <button | |||||
| class="ui mini basic button dataset-card-flavor" | |||||
| @click.stop="postStar(item, isSigned)" | |||||
| > | |||||
| <i class="ri-heart-fill" style="color: #fa8c16"></i> | |||||
| <span style="margin-left: 0.3rem">{{ | |||||
| i18n.unfavorite | |||||
| }}</span> | |||||
| </button> | |||||
| <a class="ui mini basic button card-flavor-num"> | |||||
| {{ item.NumStars }} | |||||
| </a> | |||||
| </div> | |||||
| </template> | |||||
| <template v-else> | |||||
| <div style="display: flex"> | |||||
| <button | |||||
| class="ui mini basic button dataset-card-flavor" | |||||
| @click.stop="postStar(item, isSigned)" | |||||
| > | |||||
| <i class="ri-heart-line"></i> | |||||
| <span style="margin-left: 0.3rem">{{ | |||||
| i18n.favorite | |||||
| }}</span> | |||||
| </button> | |||||
| <a class="ui mini basic button card-flavor-num"> | |||||
| {{ item.NumStars }} | |||||
| </a> | |||||
| </div> | |||||
| </template> | |||||
| </div> | |||||
| <div style="font-size: 12px; margin-top: 5px"> | |||||
| <a | |||||
| v-if="item.Category" | |||||
| :href="'/explore/datasets?category=' + item.Category" | |||||
| class="ui repo-topic label topic" | |||||
| >{{ i18n[item.Category] || item.Category }}</a | |||||
| > | |||||
| <a | |||||
| v-if="item.Task" | |||||
| :href="'/explore/datasets?task=' + item.Task" | |||||
| class="ui repo-topic label topic" | |||||
| >{{ i18n[item.Task] || item.Task }}</a | |||||
| > | |||||
| <a | |||||
| v-if="item.License" | |||||
| :href="'/explore/datasets?license=' + item.License" | |||||
| class="ui repo-topic label topic" | |||||
| >{{ item.License }}</a | |||||
| > | |||||
| </div> | |||||
| <div class="description card-flavor-desc"> | |||||
| <p>{{ item.Description }}</p> | |||||
| </div> | |||||
| </div> | |||||
| <div | |||||
| class="extra content" | |||||
| style="border-top: none !important" | |||||
| > | |||||
| <div style="display: flex; align-items: center"> | |||||
| <a | |||||
| :href="'/' + item.Repo.OwnerName" | |||||
| :title="item.Repo.OwnerName" | |||||
| > | |||||
| <img | |||||
| class="ui avatar image" | |||||
| style="width: 22px; height: 22px" | |||||
| :src="'/user/avatar/' + item.Repo.OwnerName + '/-1'" | |||||
| /> | |||||
| </a> | |||||
| <span | |||||
| style=" | |||||
| color: #999999; | |||||
| font-size: 12px; | |||||
| margin-left: 0.5rem; | |||||
| " | |||||
| >{{ item.CreatedUnix | transformTimestamp }}</span | |||||
| > | |||||
| <span | |||||
| style=" | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: center; | |||||
| margin: 0 1rem; | |||||
| " | |||||
| :title="i18n.citations" | |||||
| > | |||||
| <i class="ri-link"></i> | |||||
| <span | |||||
| style=" | |||||
| color: #101010; | |||||
| font-size: 12px; | |||||
| margin-left: 0.2rem; | |||||
| " | |||||
| >{{ item.UseCount }}</span | |||||
| > | |||||
| </span> | |||||
| <span | |||||
| style="display: flex; align-items: center; flex: 1" | |||||
| :title="i18n.downloads" | |||||
| > | |||||
| <i class="ri-download-line"></i> | |||||
| <span | |||||
| style=" | |||||
| color: #101010; | |||||
| font-size: 12px; | |||||
| margin-left: 0.2rem; | |||||
| " | |||||
| >{{ item.DownloadTimes }}</span | |||||
| > | |||||
| </span> | |||||
| <button | |||||
| class="ui mini button" | |||||
| :class="{ disabled1: !canWrite }" | |||||
| @click.stop=" | |||||
| cancelReferData(item.ID, item.Title, canWrite) | |||||
| " | |||||
| > | |||||
| {{ i18n.disassociate }} | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <template v-else> | |||||
| <div class="ui container"> | |||||
| <div class="ui mobile reversed stackable grid"> | |||||
| <div class="row" style="justify-content: space-between"> | |||||
| <div class="ui blue small menu compact selectcloudbrain"> | |||||
| <a class="item" :href="`${repoLink}/datasets`">{{ | |||||
| i18n.current_dataset | |||||
| }}</a> | |||||
| <a | |||||
| class="active item" | |||||
| :href="`${repoLink}/datasets/reference_datasets`" | |||||
| >{{ i18n.linked_datasets }}</a | |||||
| > | |||||
| </div> | |||||
| <button class="ui green button" @click="openDataset()"> | |||||
| {{ i18n.linked_datasets }} | |||||
| </button> | |||||
| </div> | |||||
| </div> | |||||
| <div class="ui placeholder segment bgtask-none"> | |||||
| <div class="ui icon header bgtask-header-pic"></div> | |||||
| <div class="bgtask-content-header">{{ i18n.not_link_dataset }}</div> | |||||
| <div class="bgtask-content"> | |||||
| <div class="bgtask-content-txt"> | |||||
| {{ i18n.no_link_dataset_tips1 }} | |||||
| </div> | |||||
| <div class="bgtask-content-txt"> | |||||
| {{ i18n.dataset_instructions_for_use | |||||
| }}<a href="https://git.openi.org.cn/zeizei/OpenI_Learning">{{ | |||||
| i18n.dataset_camp_course | |||||
| }}</a> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </template> | |||||
| <el-dialog | |||||
| :title="i18n.linked_datasets" | |||||
| :visible.sync="dialogVisible" | |||||
| :width="dialogWidth" | |||||
| @closed="refreshData" | |||||
| > | |||||
| <div class="ui icon input dataset-search-vue"> | |||||
| <i | |||||
| class="search icon" | |||||
| style="cursor: pointer; pointer-events: auto" | |||||
| @click="searchName" | |||||
| ></i> | |||||
| <input | |||||
| type="text" | |||||
| :placeholder="i18n.search_dataset" | |||||
| v-model="search" | |||||
| @keydown.enter.stop.prevent="searchName" | |||||
| /> | |||||
| </div> | |||||
| <el-row> | |||||
| <el-col | |||||
| :span="17" | |||||
| style=" | |||||
| padding-right: 1rem; | |||||
| border-right: 1px solid #f5f5f6; | |||||
| position: relative; | |||||
| " | |||||
| > | |||||
| <el-tabs v-model="activeName"> | |||||
| <el-tab-pane :label="i18n.public_dataset" name="first"> | |||||
| <el-row v-loading="loadingPublicPage"> | |||||
| <el-checkbox-group | |||||
| v-model="checkList" | |||||
| style="font-size: 14px; line-height: 1" | |||||
| > | |||||
| <div | |||||
| v-for="(item, index) in publicDatasetList" | |||||
| :key="index" | |||||
| class="select-data-wrap" | |||||
| > | |||||
| <div class="dataset-header-vue"> | |||||
| <el-checkbox | |||||
| :label="item.ID" | |||||
| @change="(checked) => changeCheckbox(checked, item)" | |||||
| :title="item.Title" | |||||
| class="select-data-title" | |||||
| style="display: flex; align-items: end" | |||||
| ><span class="ref-data-title"> | |||||
| <span | |||||
| style="overflow: hidden; text-overflow: ellipsis" | |||||
| > | |||||
| {{ item.Title }} | |||||
| </span> | |||||
| <img | |||||
| v-if="item.Recommend" | |||||
| src="/img/jian.svg" | |||||
| style="margin-left: 0.5rem" | |||||
| /> </span | |||||
| ></el-checkbox> | |||||
| <a | |||||
| class="select-data-title select-data-href" | |||||
| :href="`/${item.Repo.OwnerName}/${item.Repo.Name}/datasets`" | |||||
| :title="`${item.Repo.OwnerName}/${item.Repo.Alias}`" | |||||
| style="font-size: 12px" | |||||
| >{{ item.Repo.OwnerName }}/{{ item.Repo.Alias }}</a | |||||
| > | |||||
| </div> | |||||
| <div class="data-multiple-wrap" :title="item.Description"> | |||||
| {{ item.Description }} | |||||
| </div> | |||||
| </div> | |||||
| </el-checkbox-group> | |||||
| </el-row> | |||||
| <div | |||||
| class="ui container" | |||||
| style="margin-top: 25px; text-align: center" | |||||
| > | |||||
| <el-pagination | |||||
| background | |||||
| @current-change="currentChange" | |||||
| :current-page="currentPage" | |||||
| :page-size="5" | |||||
| layout="total, prev, pager, next" | |||||
| :total="totalNum" | |||||
| > | |||||
| </el-pagination> | |||||
| </div> | |||||
| </el-tab-pane> | |||||
| </el-tabs> | |||||
| </el-col> | |||||
| <el-col | |||||
| :span="7" | |||||
| style=" | |||||
| display: flex; | |||||
| flex-direction: column; | |||||
| height: 100%; | |||||
| right: 0; | |||||
| position: absolute; | |||||
| padding: 0 1.5rem; | |||||
| " | |||||
| > | |||||
| <div | |||||
| style=" | |||||
| font-size: 14px; | |||||
| height: 40px; | |||||
| text-align: left; | |||||
| color: #0066ff; | |||||
| line-height: 40px; | |||||
| " | |||||
| > | |||||
| {{ i18n.selected_data_file }} | |||||
| </div> | |||||
| <div | |||||
| style=" | |||||
| flex: 1; | |||||
| margin-top: 1.5rem; | |||||
| margin-bottom: 1rem; | |||||
| overflow-y: auto; | |||||
| " | |||||
| > | |||||
| <el-checkbox-group v-model="checkList"> | |||||
| <el-checkbox | |||||
| v-for="(item, index) in selectDatasetArray" | |||||
| :key="index" | |||||
| :label="item.ID" | |||||
| :title="item.Title" | |||||
| @change="(checked) => changeCheckSelected(checked, item)" | |||||
| style="display: flex; margin: 0.5rem 0" | |||||
| ><span class="select-data-right">{{ | |||||
| item.Title | |||||
| }}</span></el-checkbox | |||||
| > | |||||
| </el-checkbox-group> | |||||
| </div> | |||||
| <div style="text-align: end"> | |||||
| <el-button | |||||
| @click.native="confirmDataset" | |||||
| size="small" | |||||
| style=" | |||||
| background: #389e0d; | |||||
| color: #fff; | |||||
| border: 1px solid #389e0d; | |||||
| " | |||||
| >{{ i18n.sure }}</el-button | |||||
| > | |||||
| </div> | |||||
| </el-col> | |||||
| </el-row> | |||||
| </el-dialog> | |||||
| </div> | |||||
| </template> | |||||
| <script> | |||||
| const { _AppSubUrl, _StaticUrlPrefix, csrf } = window.config; | |||||
| export default { | |||||
| components: {}, | |||||
| data() { | |||||
| return { | |||||
| dialogWidth: "65%", | |||||
| dialogVisible: false, | |||||
| activeName: "first", | |||||
| repoLink: "", | |||||
| datasetList: [], | |||||
| test: false, | |||||
| checkList: [], | |||||
| publicDatasetList: [], | |||||
| showFlag: true, | |||||
| search: "", | |||||
| selectDatasetArray: [], | |||||
| paramsPublics: { page: 1, q: "" }, | |||||
| i18n: {}, | |||||
| totalNum: 0, | |||||
| currentPage: 1, | |||||
| loadingLinkPage: false, | |||||
| loadingPublicPage: false, | |||||
| canWrite: true, | |||||
| isSigned: false, | |||||
| maxReferenceNum: 20, | |||||
| isCurrentUrl: true, | |||||
| }; | |||||
| }, | |||||
| methods: { | |||||
| openDataset() { | |||||
| this.checkList = this.datasetList.map((item) => { | |||||
| this.selectDatasetArray.push({ ID: item.ID, Title: item.Title }); | |||||
| return item.ID; | |||||
| }); | |||||
| this.dialogVisible = true; | |||||
| this.getDatasetList(); | |||||
| }, | |||||
| refreshData() { | |||||
| this.checkList = []; | |||||
| this.selectDatasetArray = []; | |||||
| }, | |||||
| gotoDataset(item) { | |||||
| window.open(`/${item.Repo.OwnerName}/${item.Repo.Name}/datasets`); | |||||
| }, | |||||
| currentChange(page) { | |||||
| this.paramsPublics.page = page; | |||||
| this.getDatasetList(); | |||||
| }, | |||||
| searchName() { | |||||
| this.paramsPublics.q = this.search; | |||||
| this.paramsPublics.page = 1; | |||||
| this.getDatasetList(); | |||||
| }, | |||||
| cancelReferData(id, name, canWrite) { | |||||
| if (!canWrite) { | |||||
| return; | |||||
| } | |||||
| let url = `${this.repoLink}/datasets/reference_datasets/${id}`; | |||||
| this.$axios | |||||
| .delete(url) | |||||
| .then((res) => { | |||||
| if (res.data.Code === 0) { | |||||
| this.$message.success(this.i18n.cancel_link_dataset.format(name)); | |||||
| let index = this.datasetList.findIndex((item) => { | |||||
| return item.ID === id; | |||||
| }); | |||||
| this.datasetList.splice(index, 1); | |||||
| if (this.datasetList.length === 0) { | |||||
| this.showFlag = false; | |||||
| } | |||||
| } else { | |||||
| this.$message.error(res.data.Message); | |||||
| } | |||||
| }) | |||||
| .catch((err) => { | |||||
| this.$message.error(this.i18n.dataset_link_failed); | |||||
| console.log(err); | |||||
| }); | |||||
| }, | |||||
| confirmDataset() { | |||||
| this.submitReferDataset(); | |||||
| this.dialogVisible = false; | |||||
| }, | |||||
| changeCheckbox(checked, item) { | |||||
| if (this.checkList.length > this.maxReferenceNum) { | |||||
| this.checkList.pop(); | |||||
| this.$message.error( | |||||
| this.i18n.dataset_over_nums.format(this.maxReferenceNum) | |||||
| ); | |||||
| return; | |||||
| } | |||||
| if (this.checkList.length === this.maxReferenceNum && !checked) { | |||||
| this.$message.error( | |||||
| this.i18n.dataset_over_nums.format(this.maxReferenceNum) | |||||
| ); | |||||
| return; | |||||
| } | |||||
| if (checked) { | |||||
| this.selectDatasetArray.push({ ID: item.ID, Title: item.Title }); | |||||
| } else { | |||||
| let index = this.selectDatasetArray.findIndex((element) => { | |||||
| return element.ID === item.ID; | |||||
| }); | |||||
| this.selectDatasetArray.splice(index, 1); | |||||
| } | |||||
| }, | |||||
| changeCheckSelected(checked, item) { | |||||
| if (!checked) { | |||||
| let index = this.selectDatasetArray.findIndex((element) => { | |||||
| return element.ID === item.ID; | |||||
| }); | |||||
| this.selectDatasetArray.splice(index, 1); | |||||
| } | |||||
| }, | |||||
| postStar(item, isSigned) { | |||||
| if (!isSigned) { | |||||
| return; | |||||
| } | |||||
| if (item.IsStaring) { | |||||
| let url = `${this.repoLink}/datasets/${item.ID}/unstar`; | |||||
| this.$axios.put(url).then((res) => { | |||||
| if (res.data.Code === 0) { | |||||
| this.datasetList.forEach((element, i) => { | |||||
| if (element.ID === item.ID) { | |||||
| this.datasetList[i].NumStars -= 1; | |||||
| this.datasetList[i].IsStaring = !this.datasetList[i].IsStaring; | |||||
| } | |||||
| }); | |||||
| } | |||||
| }); | |||||
| } else { | |||||
| let url = `${this.repoLink}/datasets/${item.ID}/star`; | |||||
| this.$axios.put(url).then((res) => { | |||||
| if (res.data.Code === 0) { | |||||
| this.datasetList.forEach((element, i) => { | |||||
| if (element.ID === item.ID) { | |||||
| this.datasetList[i].NumStars += 1; | |||||
| this.datasetList[i].IsStaring = !this.datasetList[i].IsStaring; | |||||
| } | |||||
| }); | |||||
| } | |||||
| }); | |||||
| } | |||||
| }, | |||||
| getSelectDatasetList() { | |||||
| this.loadingLinkPage = true; | |||||
| let url = `${this.repoLink}/datasets/reference_datasets_data`; | |||||
| this.$axios.get(url).then((res) => { | |||||
| this.loadingLinkPage = false; | |||||
| if (!res.data) { | |||||
| this.showFlag = false; | |||||
| this.datasetList = []; | |||||
| return; | |||||
| } else { | |||||
| this.datasetList = res.data; | |||||
| this.datasetList.length | |||||
| ? (this.showFlag = true) | |||||
| : (this.showFlag = false); | |||||
| } | |||||
| }); | |||||
| }, | |||||
| getDatasetList() { | |||||
| this.loadingPublicPage = true; | |||||
| let url = `${this.repoLink}/datasets/reference_datasets_available`; | |||||
| this.$axios | |||||
| .get(url, { | |||||
| params: this.paramsPublics, | |||||
| }) | |||||
| .then((res) => { | |||||
| this.publicDatasetList = JSON.parse(res.data.data); | |||||
| this.totalNum = parseInt(res.data.count); | |||||
| this.loadingPublicPage = false; | |||||
| }); | |||||
| }, | |||||
| submitReferDataset() { | |||||
| if (this.checkList.length > this.maxReferenceNum) { | |||||
| this.$message.error( | |||||
| this.i18n.dataset_over_nums.format(this.maxReferenceNum) | |||||
| ); | |||||
| return; | |||||
| } | |||||
| let url = `${this.repoLink}/datasets/reference_datasets`; | |||||
| let data = this.qs.stringify( | |||||
| { | |||||
| _csrf: csrf, | |||||
| dataset_id: this.checkList, | |||||
| }, | |||||
| { arrayFormat: "repeat" } | |||||
| ); | |||||
| this.$axios | |||||
| .post(url, data) | |||||
| .then((res) => { | |||||
| if (res.data.Code === 0) { | |||||
| this.$message.success(this.i18n.dataset_link_success); | |||||
| this.getSelectDatasetList(); | |||||
| } else { | |||||
| this.$message.error(res.data.Message); | |||||
| } | |||||
| }) | |||||
| .catch((err) => { | |||||
| this.$message.error(this.i18n.dataset_link_failed); | |||||
| console.log(err); | |||||
| }); | |||||
| }, | |||||
| }, | |||||
| filters: { | |||||
| 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 dateString = Y + M + D; | |||||
| return dateString; | |||||
| }, | |||||
| }, | |||||
| watch: { | |||||
| search(val) { | |||||
| if (!val) { | |||||
| this.searchName(); | |||||
| } | |||||
| }, | |||||
| showFlag(val) { | |||||
| if (!val || this.isCurrentUrl) { | |||||
| document | |||||
| .getElementById("header-dataset") | |||||
| .setAttribute("href", this.repoLink + "/datasets"); | |||||
| } else { | |||||
| document | |||||
| .getElementById("header-dataset") | |||||
| .setAttribute("href", this.repoLink + "/datasets/reference_datasets"); | |||||
| } | |||||
| }, | |||||
| }, | |||||
| mounted() { | |||||
| this.getSelectDatasetList(); | |||||
| }, | |||||
| created() { | |||||
| this.repoLink = $(".reference-dataset").data("repolink") || ""; | |||||
| this.canWrite = $(".reference-dataset").data("canwrite"); | |||||
| this.isSigned = $(".reference-dataset").data("is-sign"); | |||||
| this.maxReferenceNum = $(".reference-dataset").data("max-reference-num"); | |||||
| this.isCurrentUrl = $(".reference-dataset").data("address"); | |||||
| if (document.documentElement.attributes["lang"].nodeValue == "en-US") { | |||||
| this.i18n = this.$locale.US; | |||||
| } else { | |||||
| this.i18n = this.$locale.CN; | |||||
| } | |||||
| }, | |||||
| beforeDestroy() {}, | |||||
| }; | |||||
| </script> | |||||
| <style scoped> | |||||
| .dataset-search-vue { | |||||
| z-index: 9999; | |||||
| position: absolute; | |||||
| right: 31%; | |||||
| height: 30px; | |||||
| top: 60px; | |||||
| } | |||||
| .refer-dataset-card { | |||||
| cursor: pointer; | |||||
| box-shadow: 0px 4px 4px 0px rgba(232, 232, 232, 0.6); | |||||
| border: 1px solid rgba(232, 232, 232, 1); | |||||
| } | |||||
| .refer-dataset-card .refer-dataset-card-content { | |||||
| font-size: 16px; | |||||
| color: #0366d6; | |||||
| font-family: SourceHanSansSC-medium; | |||||
| height: 34px; | |||||
| font-weight: bold; | |||||
| display: flex; | |||||
| align-items: center; | |||||
| justify-content: space-between; | |||||
| } | |||||
| .refer-dataset-card-title { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| max-width: 80%; | |||||
| width: 100%; | |||||
| } | |||||
| .dataset-card-flavor { | |||||
| display: flex; | |||||
| align-items: center; | |||||
| padding: 0.3rem 0.5rem; | |||||
| border: #888888; | |||||
| border-top-right-radius: 0 !important; | |||||
| border-bottom-right-radius: 0 !important; | |||||
| margin-right: -1px; | |||||
| } | |||||
| .card-flavor-num { | |||||
| padding: 0.5rem; | |||||
| border: #888888; | |||||
| border-top-left-radius: 0 !important; | |||||
| border-bottom-left-radius: 0 !important; | |||||
| cursor: default !important; | |||||
| } | |||||
| .card-flavor-desc { | |||||
| -webkit-box-orient: vertical; | |||||
| -webkit-line-clamp: 2; | |||||
| display: -webkit-box; | |||||
| overflow: hidden; | |||||
| color: #999999; | |||||
| font-size: 14px; | |||||
| margin-top: 10px; | |||||
| } | |||||
| .select-data-wrap { | |||||
| padding: 1rem 0; | |||||
| border-bottom: 1px solid rgba(0, 0, 0, 0.05); | |||||
| } | |||||
| .select-data-title { | |||||
| flex: 1; | |||||
| overflow: hidden; | |||||
| } | |||||
| .select-data-title .ref-data-title { | |||||
| font-size: 18px; | |||||
| color: #454545; | |||||
| font-weight: 700; | |||||
| display: flex; | |||||
| align-items: baseline; | |||||
| max-width: 100%; | |||||
| } | |||||
| .select-data-href { | |||||
| text-align: right; | |||||
| text-overflow: ellipsis; | |||||
| max-width: 35%; | |||||
| word-break: initial; | |||||
| margin-left: 1rem; | |||||
| } | |||||
| /deep/ .el-checkbox-group .el-checkbox .el-checkbox__label { | |||||
| display: flex; | |||||
| max-width: 90%; | |||||
| } | |||||
| .select-data-right { | |||||
| overflow: hidden; | |||||
| vertical-align: middle; | |||||
| text-overflow: ellipsis; | |||||
| max-width: 100%; | |||||
| display: inline-block; | |||||
| } | |||||
| .data-multiple-wrap { | |||||
| -webkit-line-clamp: 3; | |||||
| -webkit-box-orient: vertical; | |||||
| display: -webkit-box; | |||||
| max-width: 100%; | |||||
| overflow: hidden; | |||||
| padding-top: 1rem; | |||||
| color: #888888; | |||||
| font: 12px; | |||||
| line-height: 20px; | |||||
| margin-left: 2rem; | |||||
| } | |||||
| .disabled1 { | |||||
| opacity: 0.45 !important; | |||||
| } | |||||
| </style> | |||||
| @@ -141,6 +141,15 @@ | |||||
| class="dataset-repolink dataset-nowrap" | class="dataset-repolink dataset-nowrap" | ||||
| @click.stop="return false;" | @click.stop="return false;" | ||||
| > | > | ||||
| <i | |||||
| class="ri-links-line" | |||||
| style="color: #21ba45; margin-right: 0.3rem" | |||||
| title="关联数据集" | |||||
| v-if=" | |||||
| '/' + data.Repo.OwnerName + '/' + data.Repo.Name !== | |||||
| repoLink | |||||
| " | |||||
| ></i> | |||||
| <a | <a | ||||
| :href=" | :href=" | ||||
| '/' + | '/' + | ||||
| @@ -0,0 +1,123 @@ | |||||
| export const i18nVue = { | |||||
| CN: { | |||||
| computer_vision: "计算机视觉", | |||||
| natural_language_processing: "自然语言处理", | |||||
| speech_processing: "语音处理", | |||||
| computer_vision_natural_language_processing: "计算机视觉、自然语言处理", | |||||
| machine_translation: "机器翻译", | |||||
| question_answering_system: "问答系统", | |||||
| information_retrieval: "信息检索", | |||||
| knowledge_graph: "知识图谱", | |||||
| text_annotation: "文本标注", | |||||
| text_categorization: "文本分类", | |||||
| emotion_analysis: "情感分析", | |||||
| language_modeling: "语言建模", | |||||
| speech_recognition: "语音识别", | |||||
| automatic_digest: "自动文摘", | |||||
| information_extraction: "信息抽取", | |||||
| description_generation: "说明生成", | |||||
| image_classification: "图像分类", | |||||
| face_recognition: "人脸识别", | |||||
| image_search: "图像搜索", | |||||
| target_detection: "目标检测", | |||||
| image_description_generation: "图像描述生成", | |||||
| vehicle_license_plate_recognition: "车辆车牌识别", | |||||
| medical_image_analysis: "医学图像分析", | |||||
| unmanned: "无人驾驶", | |||||
| unmanned_security: "无人安防", | |||||
| drone: "无人机", | |||||
| vr_ar: "VR/AR", | |||||
| "2_d_vision": "2-D视觉", | |||||
| "2_5_d_vision": "2.5-D视觉", | |||||
| "3_d_reconstruction": "3D重构", | |||||
| image_processing: "图像处理", | |||||
| video_processing: "视频处理", | |||||
| visual_input_system: "视觉输入系统", | |||||
| speech_coding: "语音编码", | |||||
| speech_enhancement: "语音增强", | |||||
| speech_recognition: "语音识别", | |||||
| speech_synthesis: "语音合成", | |||||
| current_dataset: "当前数据集", | |||||
| linked_datasets: "关联数据集", | |||||
| unfavorite: "取消收藏", | |||||
| favorite: "收藏", | |||||
| disassociate: "取消关联", | |||||
| public_dataset: "公开数据集", | |||||
| selected_data_file: "已选数据集", | |||||
| sure: "确定", | |||||
| search_dataset: "搜数据集名称/描述...", | |||||
| citations: "引用次数", | |||||
| downloads: "下载次数", | |||||
| not_link_dataset: "还未关联过数据集", | |||||
| no_link_dataset_tips1: | |||||
| "您可以通过单击新建关联数据集按钮,将平台上公开数据集展示在这里。", | |||||
| dataset_instructions_for_use: "使用说明:可以参考启智AI协作平台", | |||||
| dataset_camp_course: "小白训练营课程", | |||||
| dataset_link_success: "关联数据集成功!", | |||||
| dataset_link_failed: "关联数据集失败!", | |||||
| dataset_over_nums: "关联超过?个数据集", | |||||
| cancel_link_dataset: "取消?关联数据集成功!", | |||||
| }, | |||||
| US: { | |||||
| computer_vision: "computer vision", | |||||
| natural_language_processing: "natural language processing", | |||||
| speech_processing: "speech processing", | |||||
| computer_vision_natural_language_processing: | |||||
| "computer vision and natural language processing", | |||||
| machine_translation: "machine translation", | |||||
| question_answering_system: "question answering system", | |||||
| information_retrieval: "information retrieval", | |||||
| knowledge_graph: "knowledge graph", | |||||
| text_annotation: "text annotation", | |||||
| text_categorization: "text categorization", | |||||
| emotion_analysis: "emotion analysis", | |||||
| language_modeling: "language modeling", | |||||
| speech_recognition: "speech recognition", | |||||
| automatic_digest: "automatic digest", | |||||
| information_extraction: "information extraction", | |||||
| description_generation: "description generation", | |||||
| image_classification: "image classification", | |||||
| face_recognition: "face recognition", | |||||
| image_search: "image search", | |||||
| target_detection: "target detection", | |||||
| image_description_generation: "image description generation", | |||||
| vehicle_license_plate_recognition: "vehicle license plate recognition", | |||||
| medical_image_analysis: "medical image analysis", | |||||
| unmanned: "unmanned", | |||||
| unmanned_security: "unmanned security", | |||||
| drone: "drone", | |||||
| vr_ar: "VR/AR", | |||||
| "2_d_vision": "2.D vision", | |||||
| "2.5_d_vision": "2.5D vision", | |||||
| "3_d_reconstruction": "3Dreconstruction", | |||||
| image_processing: "image processing", | |||||
| video_processing: "video processing", | |||||
| visual_input_system: "visual input system", | |||||
| speech_coding: "speech coding", | |||||
| speech_enhancement: "speech enhancement", | |||||
| speech_recognition: "speech recognition", | |||||
| speech_synthesis: "speech synthesis", | |||||
| current_dataset: "Current Dataset", | |||||
| linked_datasets: "Linked Datasets", | |||||
| unfavorite: "Unfavorite", | |||||
| favorite: "Favorite", | |||||
| disassociate: "Disassociate", | |||||
| public_dataset: "Public Dataset", | |||||
| selected_data_file: "Selected DataSets", | |||||
| sure: "Ok", | |||||
| search_dataset: "Search dataset name/description ...", | |||||
| citations: "Citations", | |||||
| downloads: "Downloads", | |||||
| not_link_dataset: "No datasets have been associated yet", | |||||
| no_link_dataset_tips1: | |||||
| "You can display public datasets on the platform here by clicking the New Linked Dataset button.", | |||||
| dataset_instructions_for_use: | |||||
| "Instructions for use: You can refer to Qizhi AI Collaboration Platform ", | |||||
| dataset_camp_course: "Newcomer Training Camp Course", | |||||
| dataset_link_success: "Linked dataset succeeded!", | |||||
| dataset_link_failed: "Linked dataset Failed!", | |||||
| dataset_over_nums: "Linked over ? datasets!", | |||||
| cancel_link_dataset: "Cancel ? Linked dataset succeeded!", | |||||
| }, | |||||
| }; | |||||
| @@ -46,15 +46,19 @@ import initCloudrain from "./features/cloudrbanin.js"; | |||||
| import initCloudrainSow from "./features/cloudbrainShow.js"; | import initCloudrainSow from "./features/cloudbrainShow.js"; | ||||
| import initImage from "./features/images.js"; | import initImage from "./features/images.js"; | ||||
| import selectDataset from "./components/dataset/selectDataset.vue"; | import selectDataset from "./components/dataset/selectDataset.vue"; | ||||
| import referenceDataset from "./components/dataset/referenceDataset.vue"; | |||||
| // import $ from 'jquery.js' | // import $ from 'jquery.js' | ||||
| import router from "./router/index.js"; | import router from "./router/index.js"; | ||||
| import { Message } from "element-ui"; | import { Message } from "element-ui"; | ||||
| import { i18nVue } from "./features/i18nVue.js"; | |||||
| Vue.use(ElementUI); | Vue.use(ElementUI); | ||||
| Vue.prototype.$axios = axios; | Vue.prototype.$axios = axios; | ||||
| Vue.prototype.$Cookies = Cookies; | Vue.prototype.$Cookies = Cookies; | ||||
| Vue.prototype.qs = qs; | Vue.prototype.qs = qs; | ||||
| Vue.prototype.$message = Message; | Vue.prototype.$message = Message; | ||||
| Vue.prototype.$locale = i18nVue; | |||||
| const { AppSubUrl, StaticUrlPrefix, csrf } = window.config; | const { AppSubUrl, StaticUrlPrefix, csrf } = window.config; | ||||
| Object.defineProperty(Vue.prototype, "$echarts", { | Object.defineProperty(Vue.prototype, "$echarts", { | ||||
| @@ -2900,6 +2904,7 @@ $(document).ready(async () => { | |||||
| initVueDataAnalysis(); | initVueDataAnalysis(); | ||||
| initVueWxAutorize(); | initVueWxAutorize(); | ||||
| initVueselectDataset(); | initVueselectDataset(); | ||||
| initVuereferenceDataset(); | |||||
| initTeamSettings(); | initTeamSettings(); | ||||
| initCtrlEnterSubmit(); | initCtrlEnterSubmit(); | ||||
| initNavbarContentToggle(); | initNavbarContentToggle(); | ||||
| @@ -4532,6 +4537,16 @@ function initVueselectDataset() { | |||||
| render: (h) => h(selectDataset), | render: (h) => h(selectDataset), | ||||
| }); | }); | ||||
| } | } | ||||
| function initVuereferenceDataset() { | |||||
| const el = document.getElementById("reference-dataset"); | |||||
| if (!el) { | |||||
| return; | |||||
| } | |||||
| new Vue({ | |||||
| el: el, | |||||
| render: (h) => h(referenceDataset), | |||||
| }); | |||||
| } | |||||
| window.timeAddManual = function () { | window.timeAddManual = function () { | ||||
| $(".mini.modal") | $(".mini.modal") | ||||
| .modal({ | .modal({ | ||||