| @@ -2,7 +2,7 @@ | |||
| <h1><img src="public/img/favicon.png" alt="logo" width="30" height="30">AiForge - 启智AI开发协作平台</h1> | |||
| [](https://git.openi.org.cn/OpenI/aiforge/releases/latest) | |||
| [](https://git.openi.org.cn/OpenI/aiforge/releases/latest) | |||
| [](https://opensource.org/licenses/MIT) | |||
| @@ -1556,6 +1556,18 @@ func GetUserByActivateEmail(email string) (*User, error) { | |||
| if len(users) >= 1 { | |||
| return &users[0],nil | |||
| }else { | |||
| // Finally, if email address is the protected email address:用户邮件地址设置为隐藏电子邮件地址 | |||
| if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) { | |||
| username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) | |||
| user := &User{LowerName: username} | |||
| has, err := ctx.e.Get(user) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| if has { | |||
| return user, nil | |||
| } | |||
| } | |||
| return nil, errors.New("cannot find user by email") | |||
| } | |||
| } | |||
| @@ -831,6 +831,7 @@ fork = Fork | |||
| download_archive = Download Repository | |||
| no_desc = No Description | |||
| no_label = No labels | |||
| quick_guide = Quick Guide | |||
| clone_this_repo = Clone this repository | |||
| create_new_repo_command = Creating a new repository on the command line | |||
| @@ -833,6 +833,7 @@ fork=派生 | |||
| download_archive=下载此项目 | |||
| no_desc=暂无描述 | |||
| no_label = 暂无标签 | |||
| quick_guide=快速帮助 | |||
| clone_this_repo=克隆当前项目 | |||
| create_new_repo_command=从命令行创建一个新的项目 | |||
| @@ -154,7 +154,7 @@ | |||
| {{svg "octicon-person" 16}} {{.i18n.Tr "register"}} | |||
| </a> | |||
| {{end}} | |||
| <a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login?redirect_to={{.Link}}"> | |||
| <a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login"> | |||
| {{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} | |||
| </a> | |||
| </div><!-- end anonymous right menu --> | |||
| @@ -154,7 +154,7 @@ | |||
| {{svg "octicon-person" 16}} {{.i18n.Tr "register"}} | |||
| </a> | |||
| {{end}} | |||
| <a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login?redirect_to={{.Link}}"> | |||
| <a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login"> | |||
| {{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} | |||
| </a> | |||
| </div><!-- end anonymous right menu --> | |||
| @@ -187,6 +187,12 @@ | |||
| cursor: pointer; | |||
| pointer-events: none; | |||
| } | |||
| .time-show{ | |||
| font-size: 10px; | |||
| margin-top: 0.4rem; | |||
| display: inline-block; | |||
| } | |||
| </style> | |||
| <!-- 弹窗 --> | |||
| @@ -265,11 +271,21 @@ | |||
| <div class="three wide column"> | |||
| <!--任务状态 --> | |||
| <span class="ui compact button job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | |||
| <!-- <span class="ui compact button job-status" id="{{.JobID}}" data-repopath="{{$.RepoRelPath}}" data-jobid="{{.JobID}}"> | |||
| {{.Status}} | |||
| </span> | |||
| </span> --> | |||
| {{if eq .Status "STOPPED"}} | |||
| <span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-stop"></i><span style="margin-left: 0.4em;font-size: 12px;">已停止</span></span> | |||
| {{else if eq .Status "RUNNING"}} | |||
| <span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-running"></i><span style="margin-left: 0.4em;font-size: 12px;">运行中</span></span> | |||
| {{else if eq .Status "FAILED"}} | |||
| <span style="display:flex;position: relative; justify-content: flex-start;"><i class="i-round i-bg-running"></i><span style="margin-left: 0.4em;font-size: 12px;">运行失败</span></span> | |||
| {{else if eq .Status "WAITING"}} | |||
| <span style="display:flex;position: relative; justify-content: flex-start;"><i class="showCircle"></i><span style="margin-left: 0.4em;font-size: 12px;">初始化等待</span></span> | |||
| {{end}} | |||
| <!-- 任务创建时间 --> | |||
| <span class="">{{TimeSinceUnix .CreatedUnix $.Lang}}</span> | |||
| <span class="time-show">{{TimeSinceUnix .CreatedUnix $.Lang}}</span> | |||
| </div> | |||
| <div class="seven wide column text right"> | |||
| @@ -1,63 +1,52 @@ | |||
| <style> | |||
| </style> | |||
| {{if .Attachments}} | |||
| {{range .Attachments}} | |||
| <div class="ui grid item" id="{{.UUID}}"> | |||
| <div class="row"> | |||
| <div class="{{if $.Permission.CanWrite $.UnitTypeDatasets}}five{{else}}nine{{end}} wide column"> | |||
| <div class="eight wide column"> | |||
| <span class="ui right">{{.Size | FileSize}}</span> | |||
| <a class="title" href="{{.DownloadURL}}?type={{$.Type}}"> | |||
| <span class="fitted">{{svg "octicon-cloud-download" 16}}</span> {{.Name}} | |||
| {{svg "octicon-cloud-download" 16}} {{.Name}} | |||
| </a> | |||
| </div> | |||
| <div class="two wide column"> | |||
| {{.Size | FileSize}} | |||
| </div> | |||
| <div class="two wide column"> | |||
| <span class="ui text center" data-tooltip='{{$.i18n.Tr "dataset.download_count"}}' data-position="bottom right">{{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}}</span> | |||
| </div> | |||
| <div class="one wide column" style="{{if ne $.Type 0}}visibility: hidden;{{end}}"> | |||
| <span class="ui text center clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy">{{svg "octicon-file" 16}}</span> | |||
| </div> | |||
| <div class="one wide column"> | |||
| <span class="ui text center clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span> | |||
| </div> | |||
| <div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}"> | |||
| <a class="ui text center" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a> | |||
| </div> | |||
| {{if $.IsSigned}} | |||
| <div class="wide column one" style="{{if ne .DecompressState 1}}visibility: hidden;{{end}}"> | |||
| <a class="ui text center" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'><i class="fa fa-pencil-square-o" aria-hidden="true"></i></a> | |||
| <div class="eight wide column right aligned"> | |||
| <div class="ui left mini icon buttons"> | |||
| <span class="ui basic button" data-tooltip='{{$.i18n.Tr "dataset.download_count"}}' data-position="bottom right">{{svg "octicon-flame" 16}} {{(.DownloadCount | PrettyNumber)}}</span> | |||
| <span class="ui basic basic button clipboard" data-clipboard-text="{{.DownloadURL}}" data-tooltip='{{$.i18n.Tr "dataset.copy_url"}}' data-clipboard-action="copy"{{if ne $.Type 0}} style="display:none;"{{end}}>{{svg "octicon-file" 16}}</span> | |||
| <span class="ui basic basic button clipboard" data-clipboard-text="{{.FileChunk.Md5}}" data-tooltip='{{$.i18n.Tr "dataset.copy_md5"}}' data-clipboard-action="copy">{{svg "octicon-file-binary" 16}}</span> | |||
| </div> | |||
| {{end}} | |||
| {{if not .CanDel}} | |||
| <div class="two wide column"> | |||
| <a class="ui button mini" disabled='true'>{{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}}</a> | |||
| {{if ne .DecompressState 0}} | |||
| <div class="ui left mini icon buttons"> | |||
| <a class="ui basic blue button" href="datasets/dirs/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.directory"}}'>{{svg "octicon-file-directory" 16}}</a> | |||
| {{if $.IsSigned}} | |||
| <a class="ui basic blue button" href="datasets/label/{{.UUID}}?type={{$.Type}}" data-tooltip='{{$.i18n.Tr "dataset.create_label_task"}}'>{{svg "octicon-pencil" 16}}</a> | |||
| {{end}} | |||
| </div> | |||
| {{else}} | |||
| {{if $.Permission.CanWrite $.UnitTypeDatasets}} | |||
| {{end}} | |||
| {{if not .CanDel}} | |||
| <a class="ui right small disabled button">{{$.i18n.Tr "dataset.delete"}}</a> | |||
| <span style="margin-right: 10px;line-height: 34px;" class="ui text{{if .IsPrivate}} red{{else}} green{{end}}">{{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}}</span> | |||
| {{else}} | |||
| {{if $.Permission.CanWrite $.UnitTypeDatasets}} | |||
| <a class="ui right small red button" href="javascript:void(0)" data-uuid={{.UUID}} data-dataset-delete data-remove-url="{{AppSubUrl}}/attachments/delete" data-csrf="{{$.CsrfToken}}">{{$.i18n.Tr "dataset.delete"}}</a> | |||
| {{if $.Repository.IsPrivate}} | |||
| <div class="two wide column"> | |||
| <a class="ui button mini" disabled='true' data-tooltip='{{$.i18n.Tr "dataset.how_to_public"}}'>{{$.i18n.Tr "dataset.private"}}</a> | |||
| </div> | |||
| {{ else }} | |||
| <div class="two wide column"> | |||
| <div class="ui buttons mini"> | |||
| <a class="ui button mini {{if .IsPrivate}}positive active{{end}}" href="javascript:void(0)" data-dataset-status="true-{{.UUID}}" data-csrf="{{$.CsrfToken}}" data-url="{{AppSubUrl}}/attachments/private" data-uuid={{.UUID}} data-private="true" data-is-private={{.IsPrivate}}>{{$.i18n.Tr "dataset.private"}}</a> | |||
| <span data-tooltip='{{$.i18n.Tr "dataset.how_to_public"}}' style="margin-right: 10px; line-height: 34px;" class="ui text red">{{$.i18n.Tr "dataset.private"}}</span> | |||
| {{else}} | |||
| <div class="compact small ui buttons" style="margin-right: 10px;"> | |||
| <a class="ui button{{if .IsPrivate}} positive active{{end}}" href="javascript:void(0)" data-dataset-status="true-{{.UUID}}" data-csrf="{{$.CsrfToken}}" data-url="{{AppSubUrl}}/attachments/private" data-uuid={{.UUID}} data-private="true" data-is-private={{.IsPrivate}}>{{$.i18n.Tr "dataset.private"}}</a> | |||
| <div class="or"></div> | |||
| <a class="ui button mini {{if not .IsPrivate}}positive active{{end}}" href="javascript:void(0)" data-dataset-status="false-{{.UUID}}" data-csrf="{{$.CsrfToken}}" data-url="{{AppSubUrl}}/attachments/private" data-uuid={{.UUID}} data-private="false" data-is-private={{.IsPrivate}}>{{$.i18n.Tr "dataset.public"}}</a> | |||
| <a class="ui button{{if not .IsPrivate}} positive active{{end}}" href="javascript:void(0)" data-dataset-status="false-{{.UUID}}" data-csrf="{{$.CsrfToken}}" data-url="{{AppSubUrl}}/attachments/private" data-uuid={{.UUID}} data-private="false" data-is-private={{.IsPrivate}}>{{$.i18n.Tr "dataset.public"}}</a> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| {{else}} | |||
| <a class="ui right small disabled button">{{$.i18n.Tr "dataset.delete"}}</a> | |||
| <span style="margin-right: 10px;line-height: 34px;" class="ui text{{if .IsPrivate}} red{{else}} green{{end}}">{{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}}</span> | |||
| {{end}} | |||
| <div class="two wide column right aligned"> | |||
| <a class="ui red button mini" href="javascript:void(0)" data-uuid={{.UUID}} data-dataset-delete data-remove-url="{{AppSubUrl}}/attachments/delete" data-csrf="{{$.CsrfToken}}">{{$.i18n.Tr "dataset.delete"}}</a> | |||
| </div> | |||
| {{else}} | |||
| <div class="two wide column"> | |||
| <a class="ui button mini" disabled='true'>{{if .IsPrivate}} {{$.i18n.Tr "dataset.private"}} {{else}} {{$.i18n.Tr "dataset.public"}} {{end}}</a> | |||
| </div> | |||
| {{end}} | |||
| {{end}} | |||
| </div> | |||
| </div> | |||
| </div> | |||
| {{end}} | |||
| @@ -80,7 +80,7 @@ | |||
| <div class="ui sixteen wide column"> | |||
| <div class="ui two column stackable grid"> | |||
| <div class="column"> | |||
| <h2>{{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}</h2> | |||
| <strong>{{if eq .Type 0}}{{.i18n.Tr "repo.cloudbrain1"}}{{else}}{{.i18n.Tr "repo.cloudbrain2"}}{{end}}-{{.i18n.Tr "datasets"}}</strong> | |||
| </div> | |||
| <div class="column right aligned" style="z-index:1"> | |||
| <div class="ui right dropdown type jump item"> | |||
| @@ -55,6 +55,40 @@ | |||
| #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" .}} | |||
| @@ -62,7 +96,7 @@ | |||
| {{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"> | |||
| @@ -78,7 +112,8 @@ | |||
| <a class="ui button primary" href="javascript:;" id="save_topic" | |||
| data-link="{{.RepoLink}}/topics">{{.i18n.Tr "repo.topic.done"}}</a> | |||
| </div> | |||
| </div> | |||
| </div> --> | |||
| {{end}} | |||
| <div class="hide" id="validate_prompt"> | |||
| <span id="count_prompt">{{.i18n.Tr "repo.topic.count_prompt"}}</span> | |||
| @@ -232,11 +267,30 @@ | |||
| {{end}} | |||
| <p class="ui" id="repo-topics"> | |||
| <i class="grey bookmark icon"></i> | |||
| {{range .Topics}}<a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a>{{end}} | |||
| {{if and .Permission.IsAdmin (not .Repository.IsArchived)}}<a id="manage_topic">{{.i18n.Tr "repo.topic.manage_topics"}}</a>{{end}} | |||
| </p> | |||
| <div class="ui" id="repo-topics" style="display: flex;position: relative;margin-bottom: 1.0rem;"> | |||
| <i class="grey bookmark icon"></i> | |||
| <div id="repo-topics1" style="flex: 1;"> | |||
| <!-- {{if not .Topics}} | |||
| <span class="no-description text-italic">{{.i18n.Tr "repo.no_desc"}}</span> | |||
| {{end}} --> | |||
| {{range .Topics}} | |||
| <a class="ui repo-topic small label topic" href="{{AppSubUrl}}/explore/repos?q={{.Name}}&topic=1">{{.Name}}</a> | |||
| {{end}} | |||
| </div> | |||
| <div> | |||
| {{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"> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <p class="ui"> | |||
| @@ -0,0 +1,468 @@ | |||
| <template> | |||
| <div> | |||
| <div class="input-search"> | |||
| <el-input v-model="input" clearable :autofocus="true" @input="changeValue" id="topics_input" @keyup.enter.native="postTopic" placeholder="搜索或创建标签"> | |||
| </el-input> | |||
| <div class="scrolling-menu"> | |||
| <div v-if="showSearchTopic" class="item-text" v-for="(arr,i) in array" @click="addTopics(i,arr)"> | |||
| <div class="icon-wrapper"> | |||
| <i style="line-height: 1.5;color: #303643;font-weight: 900;" v-if="showInitTopic[i]" class="el-icon-check" ></i> | |||
| </div> | |||
| <div class="text">{{arr.topic_name}} </div> | |||
| </div> | |||
| <div v-if="showInputValue" class="addition item-text" @click="postTopic"> | |||
| 点击或回车添加<b class="user-add-label-text">{{input}}</b>标签 | |||
| </div> | |||
| <div v-if="showAddTopic" class="item-text" @click="addPostTopic"> | |||
| <div class="icon-wrapper"> | |||
| <i style="line-height: 1.5;color: #303643;font-weight: 900;" v-if="showAddFlage" class="el-icon-check" ></i> | |||
| </div> | |||
| <div class="text">{{input}}</div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| const {AppSubUrl, StaticUrlPrefix, csrf} = window.config; | |||
| import $ from 'jquery' | |||
| export default { | |||
| data() { | |||
| return { | |||
| input:'', | |||
| params:{}, | |||
| showInputValue:false, | |||
| showFlag:-1, | |||
| array:[], | |||
| showAddTopic:false, | |||
| showAddFlage:false, | |||
| showSearchTopic:true, | |||
| postUrl:'', | |||
| arrayTopics:[], | |||
| showInitTopic:[], | |||
| }; | |||
| }, | |||
| methods: { | |||
| addTopics(item,array){ | |||
| if(!this.showInitTopic[item]){ | |||
| this.arrayTopics.push(array.topic_name) | |||
| let topics = this.arrayTopics | |||
| let strTopics = topics.join(',') | |||
| let data = this.qs.stringify({ | |||
| _csrf:csrf, | |||
| topics:strTopics | |||
| }) | |||
| this.Post(data,topics) | |||
| this.$set(this.showInitTopic,item,true) | |||
| $('#repo-topics1').children('span').remove() | |||
| }else{ | |||
| this.arrayTopics=this.arrayTopics.filter(ele=>{ | |||
| return ele !== array.topic_name | |||
| }) | |||
| let topics = this.arrayTopics | |||
| let strTopics = topics.join(',') | |||
| let data = this.qs.stringify({ | |||
| _csrf:csrf, | |||
| topics:strTopics | |||
| }) | |||
| this.Post(data,topics) | |||
| this.$set(this.showInitTopic,item,false) | |||
| if(this.arrayTopics.length===0){ | |||
| console.log("set empty") | |||
| $('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>') | |||
| }else{ | |||
| $('#repo-topics1').children('span').remove() | |||
| } | |||
| } | |||
| }, | |||
| changeValue(){ | |||
| if (this.input === ''){ | |||
| this.array = this.arrayTopics | |||
| let data = [] | |||
| this.showInitTopic = [] | |||
| this.array.forEach((element,index) => { | |||
| let item = {} | |||
| item.topic_name = element | |||
| data.push(item) | |||
| this.showInitTopic.push(true) | |||
| }); | |||
| this.array = data | |||
| this.showInputValue = false | |||
| this.showSearchTopic = true | |||
| } | |||
| else if(this.arrayTopics.indexOf(this.input)>-1){ | |||
| this.showInputValue = false | |||
| this.showSearchTopic = false | |||
| }else{ | |||
| this.showInitTopic = [] | |||
| let timestamp=new Date().getTime() | |||
| this.params.q = this.input | |||
| this.params._ = timestamp | |||
| this.$axios.get('/api/v1/topics/search',{ | |||
| params:this.params | |||
| }).then((res)=>{ | |||
| this.array = res.data.topics | |||
| this.array.forEach((element,index) => { | |||
| if (this.arrayTopics.indexOf(element.topic_name)>-1){ | |||
| this.showInitTopic.push(true) | |||
| }else{ | |||
| this.showInitTopic.push(false) | |||
| } | |||
| }); | |||
| }) | |||
| this.showInputValue = true | |||
| this.showSearchTopic = true | |||
| } | |||
| this.showAddTopic = false | |||
| }, | |||
| Post(data,topics){ | |||
| this.$axios.post(this.postUrl,data).then(res=>{ | |||
| const viewDiv = $('#repo-topics1'); | |||
| viewDiv.children('.topic').remove(); | |||
| if (topics.length) { | |||
| const topicArray = topics; | |||
| const last = viewDiv.children('a').last(); | |||
| for (let i = 0; i < topicArray.length; i++) { | |||
| const link = $('<a class="ui repo-topic small label topic"></a>'); | |||
| link.attr( | |||
| 'href', | |||
| `${AppSubUrl}/explore/repos?q=${encodeURIComponent( | |||
| topicArray[i] | |||
| )}&topic=1` | |||
| ); | |||
| link.text(topicArray[i]); | |||
| // link.insertBefore(last); | |||
| viewDiv.append(link) | |||
| } | |||
| } | |||
| viewDiv.show(); | |||
| }) | |||
| }, | |||
| postTopic(){ | |||
| const patter = /^[\u4e00-\u9fa5a-z0-9][\u4e00-\u9fa5a-zA-Z0-9-]{0,35}$/ | |||
| let regexp = patter.test(this.input) | |||
| console.log("regexp",regexp) | |||
| if(!regexp){ | |||
| this.$notify({ | |||
| message: '主题必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符', | |||
| duration: 3000, | |||
| type:'error' | |||
| }); | |||
| return | |||
| }else{ | |||
| let topic = this.input | |||
| this.arrayTopics.push(topic) | |||
| let topics = this.arrayTopics | |||
| let strTopics = topics.join(',') | |||
| let data = this.qs.stringify({ | |||
| _csrf:csrf, | |||
| topics:strTopics | |||
| }) | |||
| this.Post(data,topics) | |||
| $('#repo-topics1').children('span').remove() | |||
| this.showInputValue = false | |||
| this.showAddTopic = true | |||
| this.showAddFlage = true | |||
| } | |||
| }, | |||
| addPostTopic(){ | |||
| if(this.showAddFlage){ | |||
| this.arrayTopics.pop() | |||
| let topics = this.arrayTopics | |||
| let strTopics = topics.join(',') | |||
| let data = this.qs.stringify({ | |||
| _csrf:csrf, | |||
| topics:strTopics | |||
| }) | |||
| this.Post(data,topics) | |||
| if(this.arrayTopics.length===0){ | |||
| console.log("add postTopic") | |||
| $('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>') | |||
| }else{ | |||
| $('#repo-topics1').children('span').remove() | |||
| } | |||
| } | |||
| else if(!this.showAddFlage){ | |||
| let topic = this.input | |||
| this.arrayTopics.push(topic) | |||
| let topics = this.arrayTopics | |||
| let strTopics = topics.join(',') | |||
| let data = this.qs.stringify({ | |||
| _csrf:csrf, | |||
| topics:strTopics | |||
| }) | |||
| this.Post(data,topics) | |||
| $('#repo-topics1').children('span').remove() | |||
| } | |||
| this.showAddFlage = !this.showAddFlage | |||
| }, | |||
| initTopics(){ | |||
| const mgrBtn = $('#manage_topic'); | |||
| const editDiv = $('#topic_edit'); | |||
| mgrBtn.on('click', (e) => { | |||
| // viewDiv.hide(); | |||
| editDiv.css('display', ''); // show Semantic UI Grid | |||
| this.input = '' | |||
| if (this.input === ''){ | |||
| this.array = this.arrayTopics | |||
| let data = [] | |||
| this.showInitTopic = [] | |||
| this.array.forEach((element,index) => { | |||
| let item = {} | |||
| item.topic_name = element | |||
| data.push(item) | |||
| this.showInitTopic.push(true) | |||
| }); | |||
| this.array = data | |||
| this.showInputValue = false | |||
| this.showSearchTopic = true | |||
| } | |||
| stopPropagation(e); | |||
| }); | |||
| $(document).bind('click',function(){ | |||
| editDiv.css('display','none'); | |||
| }) | |||
| editDiv.click(function(e){ | |||
| stopPropagation(e); | |||
| }) | |||
| function stopPropagation(e) { | |||
| var ev = e || window.event; | |||
| if (ev.stopPropagation) { | |||
| ev.stopPropagation(); | |||
| } | |||
| else if (window.event) { | |||
| window.event.cancelBubble = true;//兼容IE | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| computed:{ | |||
| }, | |||
| watch: { | |||
| input(newValue){ | |||
| if (newValue === ''){ | |||
| this.array = this.arrayTopics | |||
| let data = [] | |||
| this.showInitTopic = [] | |||
| this.array.forEach((element,index) => { | |||
| let item = {} | |||
| item.topic_name = element | |||
| data.push(item) | |||
| this.showInitTopic.push(true) | |||
| }); | |||
| this.array = data | |||
| this.showInputValue = false | |||
| this.showSearchTopic = true | |||
| } | |||
| } | |||
| }, | |||
| mounted() { | |||
| const context = this | |||
| this.postUrl = `${window.location.pathname}/topics`; | |||
| $('#repo-topics1').children('a').each(function(){ | |||
| context.arrayTopics.push($(this).text()) | |||
| }); | |||
| if(this.arrayTopics.length===0){ | |||
| $('#repo-topics1').append('<span class="no-description text-italic">暂无标签</span>') | |||
| } | |||
| this.changeValue() | |||
| } , | |||
| created(){ | |||
| this.initTopics(); | |||
| this.input='' | |||
| } | |||
| }; | |||
| </script> | |||
| <style scoped> | |||
| .input-search { | |||
| width: 100%; | |||
| display: -webkit-box; | |||
| display: -ms-flexbox; | |||
| display: flex; | |||
| min-width: 10rem; | |||
| white-space: nowrap; | |||
| font-size: 1rem; | |||
| position: relative; | |||
| display: inline-block; | |||
| color: rgba(0,0,0,0.8); | |||
| padding: 8px; | |||
| } | |||
| /deep/ .el-input__inner{ | |||
| border-color: #409eff; | |||
| } | |||
| .scrolling-menu{ | |||
| border-top: none !important; | |||
| padding-top: 0 !important; | |||
| padding-bottom: 0 !important; | |||
| display: block; | |||
| position: static; | |||
| overflow-y: auto; | |||
| border: none; | |||
| -webkit-box-shadow: none !important; | |||
| box-shadow: none !important; | |||
| border-radius: 0 !important; | |||
| margin: 0 !important; | |||
| min-width: 100% !important; | |||
| width: auto !important; | |||
| border-top: 1px solid rgba(34,36,38,0.15); | |||
| } | |||
| .item-text{ | |||
| border-top: none; | |||
| padding-right: calc(1.14285714rem + 17px ) !important; | |||
| line-height: 1.333; | |||
| padding-top: 0.7142857rem !important; | |||
| padding-bottom: 0.7142857rem !important; | |||
| position: relative; | |||
| cursor: pointer; | |||
| display: block; | |||
| border: none; | |||
| height: auto; | |||
| text-align: left; | |||
| border-top: none; | |||
| line-height: 1em; | |||
| color: rgba(0,0,0,0.87); | |||
| padding: 0.78571429rem 1.14285714rem !important; | |||
| font-size: 1rem; | |||
| text-transform: none; | |||
| font-weight: normal; | |||
| -webkit-box-shadow: none; | |||
| box-shadow: none; | |||
| -webkit-touch-callout: none; | |||
| display: -webkit-box; | |||
| display: -ms-flexbox; | |||
| display: flex; | |||
| -webkit-box-align: center; | |||
| -ms-flex-align: center; | |||
| align-items: center; | |||
| display: -webkit-box !important; | |||
| display: -ms-flexbox !important; | |||
| display: flex !important; | |||
| } | |||
| .icon-wrapper{ | |||
| text-align: left; | |||
| width: 24px; | |||
| height: 20px; | |||
| -ms-flex-negative: 0; | |||
| flex-shrink: 0; | |||
| } | |||
| .text{ | |||
| max-width: 80%; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| font-size: 12px; | |||
| font-weight: 400; | |||
| color: #40485b; | |||
| } | |||
| .addition{ | |||
| background: #f6f6f6; | |||
| } | |||
| .user-add-label-text{ | |||
| max-width: 80%; | |||
| overflow: hidden; | |||
| text-overflow: ellipsis; | |||
| white-space: nowrap; | |||
| margin: 0 4px; | |||
| } | |||
| </style> | |||
| @@ -1,17 +1,16 @@ | |||
| <template> | |||
| <div class="dropzone-wrapper dataset-files"> | |||
| <div class="ui pointing below red basic label"> | |||
| <i class="icon info circle"></i>只有zip格式的数据集才能发起云脑任务 | |||
| </div> | |||
| <div | |||
| id="dataset" | |||
| class="dropzone" | |||
| /> | |||
| <p class="upload-info"> | |||
| {{ file_status_text }} | |||
| <span class="success">{{ status }}</span> | |||
| <strong class="success text red">{{ status }}</strong> | |||
| </p> | |||
| <p>云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。</p> | |||
| <p>说明:<br> | |||
| - 只有zip格式的数据集才能发起云脑任务;<br> | |||
| - 云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。</p> | |||
| </div> | |||
| </template> | |||
| @@ -6,9 +6,12 @@ | |||
| /> | |||
| <p class="upload-info"> | |||
| {{ file_status_text }} | |||
| <span class="success">{{ status }}</span> | |||
| <strong class="success text red">{{ status }}</strong> | |||
| </p> | |||
| <p>说明:<br> | |||
| - 只有zip格式的数据集才能发起云脑任务;<br> | |||
| - 云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。 | |||
| </p> | |||
| <p>云脑1提供 <span class="text blue">CPU / GPU</span> 资源,云脑2提供 <span class="text blue">Ascend NPU</span> 资源;调试使用的数据集也需要上传到对应的环境。</p> | |||
| </div> | |||
| </template> | |||
| @@ -36,6 +36,7 @@ import MinioUploader from './components/MinioUploader.vue'; | |||
| import ObsUploader from './components/ObsUploader.vue'; | |||
| import EditAboutInfo from './components/EditAboutInfo.vue'; | |||
| import Images from './components/Images.vue' | |||
| import EditTopics from './components/EditTopics.vue' | |||
| Vue.use(ElementUI); | |||
| Vue.prototype.$axios = axios; | |||
| @@ -2967,11 +2968,13 @@ $(document).ready(async () => { | |||
| initVueUploader(); | |||
| initObsUploader(); | |||
| initVueEditAbout(); | |||
| initVueEditTopic(); | |||
| initVueImages(); | |||
| initTeamSettings(); | |||
| initCtrlEnterSubmit(); | |||
| initNavbarContentToggle(); | |||
| initTopicbar(); | |||
| // initTopicbar(); | |||
| // closeTopicbar(); | |||
| initU2FAuth(); | |||
| initU2FRegister(); | |||
| initIssueList(); | |||
| @@ -3666,7 +3669,19 @@ function initVueEditAbout() { | |||
| }); | |||
| } | |||
| function initVueEditTopic() { | |||
| const el = document.getElementById('topic_edit1'); | |||
| if (!el) { | |||
| return; | |||
| } | |||
| new Vue({ | |||
| el:'#topic_edit1', | |||
| render:h=>h(EditTopics) | |||
| }) | |||
| } | |||
| function initVueImages() { | |||
| const el = document.getElementById('images'); | |||
| console.log("el",el) | |||
| @@ -3677,6 +3692,7 @@ function initVueImages() { | |||
| new Vue({ | |||
| el: '#images', | |||
| render: h => h(Images) | |||
| }); | |||
| } | |||
| @@ -3932,218 +3948,243 @@ function initNavbarContentToggle() { | |||
| }); | |||
| } | |||
| function initTopicbar() { | |||
| const mgrBtn = $('#manage_topic'); | |||
| const editDiv = $('#topic_edit'); | |||
| const viewDiv = $('#repo-topics'); | |||
| const saveBtn = $('#save_topic'); | |||
| const topicDropdown = $('#topic_edit .dropdown'); | |||
| const topicForm = $('#topic_edit.ui.form'); | |||
| const topicPrompts = getPrompts(); | |||
| mgrBtn.on('click', () => { | |||
| viewDiv.hide(); | |||
| editDiv.css('display', ''); // show Semantic UI Grid | |||
| }); | |||
| function getPrompts() { | |||
| const hidePrompt = $('div.hide#validate_prompt'); | |||
| const prompts = { | |||
| countPrompt: hidePrompt.children('#count_prompt').text(), | |||
| formatPrompt: hidePrompt.children('#format_prompt').text() | |||
| }; | |||
| hidePrompt.remove(); | |||
| return prompts; | |||
| } | |||
| saveBtn.on('click', () => { | |||
| const topics = $('input[name=topics]').val(); | |||
| $.post( | |||
| saveBtn.data('link'), | |||
| { | |||
| _csrf: csrf, | |||
| topics | |||
| }, | |||
| (_data, _textStatus, xhr) => { | |||
| if (xhr.responseJSON.status === 'ok') { | |||
| viewDiv.children('.topic').remove(); | |||
| if (topics.length) { | |||
| const topicArray = topics.split(','); | |||
| const last = viewDiv.children('a').last(); | |||
| for (let i = 0; i < topicArray.length; i++) { | |||
| const link = $('<a class="ui repo-topic small label topic"></a>'); | |||
| link.attr( | |||
| 'href', | |||
| `${AppSubUrl}/explore/repos?q=${encodeURIComponent( | |||
| topicArray[i] | |||
| )}&topic=1` | |||
| ); | |||
| link.text(topicArray[i]); | |||
| link.insertBefore(last); | |||
| } | |||
| } | |||
| editDiv.css('display', 'none'); | |||
| viewDiv.show(); | |||
| } | |||
| } | |||
| ) | |||
| .fail((xhr) => { | |||
| if (xhr.status === 422) { | |||
| if (xhr.responseJSON.invalidTopics.length > 0) { | |||
| topicPrompts.formatPrompt = xhr.responseJSON.message; | |||
| const {invalidTopics} = xhr.responseJSON; | |||
| const topicLables = topicDropdown.children('a.ui.label'); | |||
| topics.split(',').forEach((value, index) => { | |||
| for (let i = 0; i < invalidTopics.length; i++) { | |||
| if (invalidTopics[i] === value) { | |||
| topicLables | |||
| .eq(index) | |||
| .removeClass('green') | |||
| .addClass('red'); | |||
| } | |||
| } | |||
| }); | |||
| } else { | |||
| topicPrompts.countPrompt = xhr.responseJSON.message; | |||
| } | |||
| } | |||
| }) | |||
| .always(() => { | |||
| topicForm.form('validate form'); | |||
| }); | |||
| }); | |||
| topicDropdown.dropdown({ | |||
| allowAdditions: true, | |||
| forceSelection: false, | |||
| fields: {name: 'description', value: 'data-value'}, | |||
| saveRemoteData: false, | |||
| label: { | |||
| transition: 'horizontal flip', | |||
| duration: 200, | |||
| variation: false, | |||
| blue: true, | |||
| basic: true | |||
| }, | |||
| className: { | |||
| label: 'ui small label' | |||
| }, | |||
| apiSettings: { | |||
| url: `${AppSubUrl}/api/v1/topics/search?q={query}`, | |||
| throttle: 500, | |||
| cache: false, | |||
| onResponse(res) { | |||
| const formattedResponse = { | |||
| success: false, | |||
| results: [] | |||
| }; | |||
| const stripTags = function (text) { | |||
| return text.replace(/<[^>]*>?/gm, ''); | |||
| }; | |||
| const query = stripTags(this.urlData.query.trim()); | |||
| let found_query = false; | |||
| const current_topics = []; | |||
| topicDropdown | |||
| .find('div.label.visible.topic,a.label.visible') | |||
| .each((_, e) => { | |||
| current_topics.push(e.dataset.value); | |||
| }); | |||
| if (res.topics) { | |||
| let found = false; | |||
| for (let i = 0; i < res.topics.length; i++) { | |||
| // skip currently added tags | |||
| if (current_topics.includes(res.topics[i].topic_name)) { | |||
| continue; | |||
| } | |||
| if ( | |||
| res.topics[i].topic_name.toLowerCase() === query.toLowerCase() | |||
| ) { | |||
| found_query = true; | |||
| } | |||
| formattedResponse.results.push({ | |||
| description: res.topics[i].topic_name, | |||
| 'data-value': res.topics[i].topic_name | |||
| }); | |||
| found = true; | |||
| } | |||
| formattedResponse.success = found; | |||
| } | |||
| if (query.length > 0 && !found_query) { | |||
| formattedResponse.success = true; | |||
| formattedResponse.results.unshift({ | |||
| description: query, | |||
| 'data-value': query | |||
| }); | |||
| } else if (query.length > 0 && found_query) { | |||
| formattedResponse.results.sort((a, b) => { | |||
| if (a.description.toLowerCase() === query.toLowerCase()) return -1; | |||
| if (b.description.toLowerCase() === query.toLowerCase()) return 1; | |||
| if (a.description > b.description) return -1; | |||
| if (a.description < b.description) return 1; | |||
| return 0; | |||
| }); | |||
| } | |||
| return formattedResponse; | |||
| } | |||
| }, | |||
| onLabelCreate(value) { | |||
| value = value.toLowerCase().trim(); | |||
| this.attr('data-value', value) | |||
| .contents() | |||
| .first() | |||
| .replaceWith(value); | |||
| return $(this); | |||
| }, | |||
| onAdd(addedValue, _addedText, $addedChoice) { | |||
| addedValue = addedValue.toLowerCase().trim(); | |||
| $($addedChoice).attr('data-value', addedValue); | |||
| $($addedChoice).attr('data-text', addedValue); | |||
| } | |||
| }); | |||
| $.fn.form.settings.rules.validateTopic = function (_values, regExp) { | |||
| const topics = topicDropdown.children('a.ui.label'); | |||
| const status = | |||
| topics.length === 0 || (topics.last().attr('data-value').match(regExp) !== null && topics.last().attr('data-value').length <= 35); | |||
| if (!status) { | |||
| topics | |||
| .last() | |||
| .removeClass('green') | |||
| .addClass('red'); | |||
| } | |||
| return status && topicDropdown.children('a.ui.label.red').length === 0; | |||
| }; | |||
| topicForm.form({ | |||
| on: 'change', | |||
| inline: true, | |||
| fields: { | |||
| topics: { | |||
| identifier: 'topics', | |||
| rules: [ | |||
| { | |||
| type: 'validateTopic', | |||
| value: /^[\u4e00-\u9fa5a-z0-9][\u4e00-\u9fa5a-z0-9-]{0,105}$/, | |||
| prompt: topicPrompts.formatPrompt | |||
| }, | |||
| { | |||
| type: 'maxCount[25]', | |||
| prompt: topicPrompts.countPrompt | |||
| } | |||
| ] | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| // function initTopicbar() { | |||
| // const mgrBtn = $('#manage_topic'); | |||
| // const editDiv = $('#topic_edit'); | |||
| // const viewDiv = $('#repo-topics'); | |||
| // const saveBtn = $('#save_topic'); | |||
| // const topicDropdown = $('#topic_edit .dropdown'); | |||
| // const topicForm = $('#topic_edit.ui.form'); | |||
| // const topicInput = $("#topics_input") | |||
| // const topicPrompts = getPrompts(); | |||
| // mgrBtn.on('click', (e) => { | |||
| // // viewDiv.hide(); | |||
| // editDiv.css('display', ''); // show Semantic UI Grid | |||
| // topicInput.val('') | |||
| // console.log("-----------------asdasd",$("#topics_input"),$("#topics_input").val()) | |||
| // stopPropagation(e); | |||
| // }); | |||
| // $(document).bind('click',function(){ | |||
| // editDiv.css('display','none'); | |||
| // }) | |||
| // editDiv.click(function(e){ | |||
| // stopPropagation(e); | |||
| // }) | |||
| // function getPrompts() { | |||
| // const hidePrompt = $('div.hide#validate_prompt'); | |||
| // const prompts = { | |||
| // countPrompt: hidePrompt.children('#count_prompt').text(), | |||
| // formatPrompt: hidePrompt.children('#format_prompt').text() | |||
| // }; | |||
| // hidePrompt.remove(); | |||
| // return prompts; | |||
| // } | |||
| // function stopPropagation(e) { | |||
| // var ev = e || window.event; | |||
| // if (ev.stopPropagation) { | |||
| // ev.stopPropagation(); | |||
| // } | |||
| // else if (window.event) { | |||
| // window.event.cancelBubble = true;//兼容IE | |||
| // } | |||
| // } | |||
| // saveBtn.on('click', () => { | |||
| // const topics = $('input[name=topics]').val(); | |||
| // $.post( | |||
| // saveBtn.data('link'), | |||
| // { | |||
| // _csrf: csrf, | |||
| // topics | |||
| // }, | |||
| // (_data, _textStatus, xhr) => { | |||
| // if (xhr.responseJSON.status === 'ok') { | |||
| // console.log("--------saveBtn------------") | |||
| // viewDiv.children('.topic').remove(); | |||
| // if (topics.length) { | |||
| // const topicArray = topics.split(','); | |||
| // const last = viewDiv.children('a').last(); | |||
| // for (let i = 0; i < topicArray.length; i++) { | |||
| // const link = $('<a class="ui repo-topic small label topic"></a>'); | |||
| // link.attr( | |||
| // 'href', | |||
| // `${AppSubUrl}/explore/repos?q=${encodeURIComponent( | |||
| // topicArray[i] | |||
| // )}&topic=1` | |||
| // ); | |||
| // link.text(topicArray[i]); | |||
| // link.insertBefore(last); | |||
| // } | |||
| // } | |||
| // editDiv.css('display', 'none'); | |||
| // viewDiv.show(); | |||
| // } | |||
| // } | |||
| // ) | |||
| // .fail((xhr) => { | |||
| // if (xhr.status === 422) { | |||
| // if (xhr.responseJSON.invalidTopics.length > 0) { | |||
| // topicPrompts.formatPrompt = xhr.responseJSON.message; | |||
| // const {invalidTopics} = xhr.responseJSON; | |||
| // const topicLables = topicDropdown.children('a.ui.label'); | |||
| // topics.split(',').forEach((value, index) => { | |||
| // for (let i = 0; i < invalidTopics.length; i++) { | |||
| // if (invalidTopics[i] === value) { | |||
| // topicLables | |||
| // .eq(index) | |||
| // .removeClass('green') | |||
| // .addClass('red'); | |||
| // } | |||
| // } | |||
| // }); | |||
| // } else { | |||
| // topicPrompts.countPrompt = xhr.responseJSON.message; | |||
| // } | |||
| // } | |||
| // }) | |||
| // .always(() => { | |||
| // topicForm.form('validate form'); | |||
| // }); | |||
| // }); | |||
| // topicDropdown.dropdown({ | |||
| // allowAdditions: true, | |||
| // forceSelection: false, | |||
| // fields: {name: 'description', value: 'data-value'}, | |||
| // saveRemoteData: false, | |||
| // label: { | |||
| // transition: 'horizontal flip', | |||
| // duration: 200, | |||
| // variation: false, | |||
| // blue: true, | |||
| // basic: true | |||
| // }, | |||
| // className: { | |||
| // label: 'ui small label' | |||
| // }, | |||
| // apiSettings: { | |||
| // url: `${AppSubUrl}/api/v1/topics/search?q={query}`, | |||
| // throttle: 500, | |||
| // cache: false, | |||
| // onResponse(res) { | |||
| // const formattedResponse = { | |||
| // success: false, | |||
| // results: [] | |||
| // }; | |||
| // const stripTags = function (text) { | |||
| // return text.replace(/<[^>]*>?/gm, ''); | |||
| // }; | |||
| // const query = stripTags(this.urlData.query.trim()); | |||
| // let found_query = false; | |||
| // const current_topics = []; | |||
| // topicDropdown | |||
| // .find('div.label.visible.topic,a.label.visible') | |||
| // .each((_, e) => { | |||
| // current_topics.push(e.dataset.value); | |||
| // }); | |||
| // if (res.topics) { | |||
| // let found = false; | |||
| // for (let i = 0; i < res.topics.length; i++) { | |||
| // // skip currently added tags | |||
| // if (current_topics.includes(res.topics[i].topic_name)) { | |||
| // continue; | |||
| // } | |||
| // if ( | |||
| // res.topics[i].topic_name.toLowerCase() === query.toLowerCase() | |||
| // ) { | |||
| // found_query = true; | |||
| // } | |||
| // formattedResponse.results.push({ | |||
| // description: res.topics[i].topic_name, | |||
| // 'data-value': res.topics[i].topic_name | |||
| // }); | |||
| // found = true; | |||
| // } | |||
| // formattedResponse.success = found; | |||
| // } | |||
| // if (query.length > 0 && !found_query) { | |||
| // formattedResponse.success = true; | |||
| // formattedResponse.results.unshift({ | |||
| // description: query, | |||
| // 'data-value': query | |||
| // }); | |||
| // } else if (query.length > 0 && found_query) { | |||
| // formattedResponse.results.sort((a, b) => { | |||
| // if (a.description.toLowerCase() === query.toLowerCase()) return -1; | |||
| // if (b.description.toLowerCase() === query.toLowerCase()) return 1; | |||
| // if (a.description > b.description) return -1; | |||
| // if (a.description < b.description) return 1; | |||
| // return 0; | |||
| // }); | |||
| // } | |||
| // return formattedResponse; | |||
| // } | |||
| // }, | |||
| // onLabelCreate(value) { | |||
| // value = value.toLowerCase().trim(); | |||
| // this.attr('data-value', value) | |||
| // .contents() | |||
| // .first() | |||
| // .replaceWith(value); | |||
| // return $(this); | |||
| // }, | |||
| // onAdd(addedValue, _addedText, $addedChoice) { | |||
| // addedValue = addedValue.toLowerCase().trim(); | |||
| // $($addedChoice).attr('data-value', addedValue); | |||
| // $($addedChoice).attr('data-text', addedValue); | |||
| // } | |||
| // }); | |||
| // $.fn.form.settings.rules.validateTopic = function (_values, regExp) { | |||
| // const topics = topicDropdown.children('a.ui.label'); | |||
| // const status = | |||
| // topics.length === 0 || (topics.last().attr('data-value').match(regExp) !== null && topics.last().attr('data-value').length <= 35); | |||
| // if (!status) { | |||
| // topics | |||
| // .last() | |||
| // .removeClass('green') | |||
| // .addClass('red'); | |||
| // } | |||
| // return status && topicDropdown.children('a.ui.label.red').length === 0; | |||
| // }; | |||
| // topicForm.form({ | |||
| // on: 'change', | |||
| // inline: true, | |||
| // fields: { | |||
| // topics: { | |||
| // identifier: 'topics', | |||
| // rules: [ | |||
| // { | |||
| // type: 'validateTopic', | |||
| // value: /^[\u4e00-\u9fa5a-z0-9][\u4e00-\u9fa5a-z0-9-]{0,105}$/, | |||
| // prompt: topicPrompts.formatPrompt | |||
| // }, | |||
| // { | |||
| // type: 'maxCount[25]', | |||
| // prompt: topicPrompts.countPrompt | |||
| // } | |||
| // ] | |||
| // } | |||
| // } | |||
| // }); | |||
| // } | |||
| window.toggleDeadlineForm = function () { | |||
| $('#deadlineForm').fadeToggle(150); | |||
| @@ -140,19 +140,32 @@ | |||
| border: 1px solid #ffffff; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| .item { | |||
| border-bottom: 1px solid rgba(34,36,38,.15); | |||
| .ui.buttons { | |||
| .button { | |||
| box-shadow: none !important; | |||
| } | |||
| } | |||
| } | |||
| .ui.grid > .row { | |||
| align-items: center; | |||
| } | |||
| .title { | |||
| font-size: 16px; | |||
| font-weight: bold; | |||
| margin: 0 6px; | |||
| margin: 0 6px; | |||
| overflow: hidden; | |||
| padding-right: 15px; | |||
| white-space: nowrap; | |||
| text-overflow: ellipsis; | |||
| display: block; | |||
| } | |||
| .directory-seperator { | |||
| padding: 0 4px; | |||
| @@ -220,3 +220,16 @@ footer .column{margin-bottom:0!important; padding-bottom:0!important;} | |||
| .ui.vertical.menu .dropdown.item .menu { | |||
| left: 50%; | |||
| } | |||
| // icon cloudbrain | |||
| .i-round{display:inline-block;width:18px;height:18px;background:url("/img/icons.svg");background-position: -496px -52px;} | |||
| .i-bg-organ{background-position: -496px -52px;} | |||
| .i-bg-stop{background-position: -459px -52px;} | |||
| .i-bg-running{background-position: -478px -52px;} | |||
| .i-bg-orange{background-position: -495px -51px;} | |||
| .i-bg-red{background-position: -532px -52px;} | |||
| .i-bg-green{background-position: -441px -52px;} | |||
| .i-bg-used{background-position: -514px -52px;} | |||
| .icon-bind{background-position: -550px -52px;} | |||
| .icon-unbind{background-position: -568px -52px;} | |||
| .showCircle{display:inline-block;background-image:url('/img/loading.gif');background-repeat:no-repeat;width:16px;height:16px;background-size:16px 16px;margin-right:5px;} | |||