| @@ -87,6 +87,8 @@ GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(fi | |||||
| WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) | WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f) | ||||
| WEBPACK_CONFIGS := webpack.config.js | WEBPACK_CONFIGS := webpack.config.js | ||||
| WEBPACK_CONFIGS_TMP := webpack_temp.config.js | |||||
| WEBPACK_CONFIGS_PRO := webpack_pro.config.js | |||||
| WEBPACK_DEST := public/js/index.js public/css/index.css | WEBPACK_DEST := public/js/index.js public/css/index.css | ||||
| WEBPACK_DEST_DIRS := public/js public/css public/fonts | WEBPACK_DEST_DIRS := public/js public/css public/fonts | ||||
| @@ -290,7 +292,7 @@ lint-backend: golangci-lint revive vet swagger-check swagger-validate test-vendo | |||||
| .PHONY: lint-frontend | .PHONY: lint-frontend | ||||
| lint-frontend: node_modules | lint-frontend: node_modules | ||||
| npx eslint web_src/js webpack.config.js | |||||
| npx eslint web_src/js $(WEBPACK_CONFIGS) | |||||
| npx stylelint web_src/less | npx stylelint web_src/less | ||||
| .PHONY: watch-frontend | .PHONY: watch-frontend | ||||
| @@ -504,7 +506,7 @@ install: $(wildcard *.go) | |||||
| build: frontend backend | build: frontend backend | ||||
| .PHONY: frontend | .PHONY: frontend | ||||
| frontend: node-check $(FOMANTIC_DEST) $(WEBPACK_DEST) | |||||
| frontend: node-check webpack_prepare $(FOMANTIC_DEST) $(WEBPACK_DEST) webpack_end | |||||
| .PHONY: backend | .PHONY: backend | ||||
| backend: go-check generate $(EXECUTABLE) | backend: go-check generate $(EXECUTABLE) | ||||
| @@ -596,6 +598,19 @@ $(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules | |||||
| .PHONY: webpack | .PHONY: webpack | ||||
| webpack: $(WEBPACK_DEST) | webpack: $(WEBPACK_DEST) | ||||
| webpack_prepare: | |||||
| if [ $(filter bindata,$(TAGS_SPLIT))x = "bindata"x ]; then \ | |||||
| echo "prepare"; \ | |||||
| cp $(WEBPACK_CONFIGS) $(WEBPACK_CONFIGS_TMP); \ | |||||
| cp $(WEBPACK_CONFIGS_PRO) $(WEBPACK_CONFIGS); \ | |||||
| fi | |||||
| webpack_end: | |||||
| if [ $(filter bindata,$(TAGS_SPLIT))x = "bindata"x ]; then \ | |||||
| echo "end"; \ | |||||
| mv $(WEBPACK_CONFIGS_TMP) $(WEBPACK_CONFIGS); \ | |||||
| fi | |||||
| $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules | $(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules | ||||
| rm -rf $(WEBPACK_DEST_DIRS) | rm -rf $(WEBPACK_DEST_DIRS) | ||||
| @@ -4,26 +4,27 @@ | |||||
| package models | package models | ||||
| import ( | |||||
| "code.gitea.io/gitea/modules/log" | |||||
| ) | |||||
| import "code.gitea.io/gitea/modules/log" | |||||
| // GetUserDataSetPermission returns the user permissions to the data_set | // GetUserDataSetPermission returns the user permissions to the data_set | ||||
| func GetUserDataSetPermission(dataSet *Dataset, user *User) (isPermit bool, err error) { | func GetUserDataSetPermission(dataSet *Dataset, user *User) (isPermit bool, err error) { | ||||
| isPermit = false | isPermit = false | ||||
| switch dataSet.Status { | |||||
| case DatasetStatusDeleted: | |||||
| log.Error("the data_set has been deleted") | |||||
| case DatasetStatusPrivate: | |||||
| if !user.IsAdmin && user.ID != dataSet.UserID { | |||||
| log.Error("the user is not admin nor the owner of the data_set") | |||||
| if user != nil { | |||||
| switch dataSet.Status { | |||||
| case DatasetStatusDeleted: | |||||
| log.Error("the data_set has been deleted") | |||||
| case DatasetStatusPrivate: | |||||
| if !user.IsAdmin && user.ID != dataSet.UserID { | |||||
| log.Error("the user is not admin nor the owner of the data_set") | |||||
| } else { | |||||
| isPermit = true | |||||
| } | |||||
| case DatasetStatusPublic: | |||||
| isPermit = true | |||||
| default: | |||||
| log.Error("the status of data_set is wrong") | |||||
| } | } | ||||
| isPermit = true | |||||
| case DatasetStatusPublic: | |||||
| isPermit = true | |||||
| default: | |||||
| log.Error("the status of data_set is wrong") | |||||
| } | } | ||||
| return isPermit, nil | return isPermit, nil | ||||
| @@ -434,7 +434,7 @@ func NotebookDel(ctx *context.Context) { | |||||
| ctx.RenderWithErr("the job has not been stopped", tplDebugJobIndex, nil) | ctx.RenderWithErr("the job has not been stopped", tplDebugJobIndex, nil) | ||||
| return | return | ||||
| } | } | ||||
| _, err := modelarts.DelNotebook2(jobID) | _, err := modelarts.DelNotebook2(jobID) | ||||
| if err != nil { | if err != nil { | ||||
| log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | log.Error("DelNotebook2(%s) failed:%v", task.JobName, err.Error()) | ||||
| @@ -579,7 +579,7 @@ func RegisterRoutes(m *macaron.Macaron) { | |||||
| m.Group("", func() { | m.Group("", func() { | ||||
| m.Get("/attachments/:uuid", repo.GetAttachment) | m.Get("/attachments/:uuid", repo.GetAttachment) | ||||
| }, reqSignIn) | |||||
| }) | |||||
| m.Group("/attachments", func() { | m.Group("/attachments", func() { | ||||
| m.Post("", repo.UploadAttachment) | m.Post("", repo.UploadAttachment) | ||||
| @@ -1,3 +1,4 @@ | |||||
| {{template "base/head" .}} | {{template "base/head" .}} | ||||
| <div class="organization profile"> | <div class="organization profile"> | ||||
| {{/* overflow: auto is the clearfix - this avoids the image going beyond | {{/* overflow: auto is the clearfix - this avoids the image going beyond | ||||
| @@ -26,7 +27,7 @@ | |||||
| <div class="ui sixteen wide computer column"> | <div class="ui sixteen wide computer column"> | ||||
| <div class="ui mobile reversed stackable grid"> | <div class="ui mobile reversed stackable grid"> | ||||
| <div class="ui sixteen wide tablet sixteen wide computer column margin-top20 pad-botom maxheight" id='key_tag'> | |||||
| <div class="ui sixteen wide tablet sixteen wide computer column margin-bottom20 pad-botom maxheight" id='key_tag'> | |||||
| {{if .OrgTopics}} | {{if .OrgTopics}} | ||||
| <a class="{{if eq $.Keyword "" }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?" >{{$.i18n.Tr "org.all_org_topics"}}</span></a> | <a class="{{if eq $.Keyword "" }} tag_bg {{end}} tag_key ui small tag_lable topic omit" href="{{$.Link}}?" >{{$.i18n.Tr "org.all_org_topics"}}</span></a> | ||||
| {{end}} | {{end}} | ||||
| @@ -38,9 +39,12 @@ | |||||
| </a> | </a> | ||||
| {{end}} | {{end}} | ||||
| {{end}} | {{end}} | ||||
| </div> | |||||
| <div style="width: 100%;margin:5px 5px 10px;"> | |||||
| <a class="text-right" onclick="isUnfold()" id="icon_btn"><i class="ri-arrow-down-s-line" style="display:inline-block;vertical-align:top"></i> {{.i18n.Tr "org.unfold"}}</a> | |||||
| {{if .OrgTopics}} | |||||
| <a class=" tag_key ui small tag_lable topic omit icon_a" onclick="isUnfold()" id="icon_btn" > | |||||
| <i class="ri-arrow-down-s-line" style="display:inline-block;vertical-align:top"></i> | |||||
|  {{.i18n.Tr "org.unfold"}} | |||||
| </a> | |||||
| {{end}} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -131,16 +135,15 @@ | |||||
| <script> | <script> | ||||
| function isUnfold(){ | |||||
| var isContain= document.querySelector("#key_tag").classList.contains("maxheight"); | |||||
| if(isContain){ | |||||
| document.querySelector("#key_tag").classList.remove("maxheight"); | |||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | |||||
| }else{ | |||||
| document.querySelector("#key_tag").classList.add("maxheight"); | |||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | |||||
| function isUnfold(){ | |||||
| var isContain= document.querySelector("#key_tag").classList.contains("maxheight"); | |||||
| if(isContain){ | |||||
| document.querySelector("#key_tag").classList.remove("maxheight"); | |||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-up-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.fold"}}" | |||||
| }else{ | |||||
| document.querySelector("#key_tag").classList.add("maxheight"); | |||||
| document.getElementById("icon_btn").innerHTML="<i class=\"ri-arrow-down-s-line\" style=\"display:inline-block;vertical-align:top\"></i>   {{.i18n.Tr "org.unfold"}}" | |||||
| } | |||||
| } | } | ||||
| } | |||||
| </script> | </script> | ||||
| @@ -759,8 +759,8 @@ display: block; | |||||
| background-color: #0366D6 !important; | background-color: #0366D6 !important; | ||||
| color:#FFFFFF !important; | color:#FFFFFF !important; | ||||
| } | } | ||||
| .margin-top20{ | |||||
| margin-top: 20px; | |||||
| .margin-bottom20{ | |||||
| margin-bottom: 20px; | |||||
| } | } | ||||
| .maxheight{ | .maxheight{ | ||||
| max-height: 88px; | max-height: 88px; | ||||
| @@ -768,4 +768,13 @@ display: block; | |||||
| } | } | ||||
| .pad-botom{ | .pad-botom{ | ||||
| padding-bottom:0px !important; | padding-bottom:0px !important; | ||||
| } | |||||
| .icon_a{ | |||||
| position: absolute; | |||||
| right: 0; | |||||
| bottom: .2em; | |||||
| background: #FFF; | |||||
| border: none !important; | |||||
| color: #0366d6 !important; | |||||
| box-shadow: -15px 0px 10px #fff; | |||||
| } | } | ||||
| @@ -0,0 +1,274 @@ | |||||
| const cssnano = require('cssnano'); | |||||
| const fastGlob = require('fast-glob'); | |||||
| const FixStyleOnlyEntriesPlugin = require('webpack-fix-style-only-entries'); | |||||
| const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |||||
| const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin'); | |||||
| const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | |||||
| const PostCSSPresetEnv = require('postcss-preset-env'); | |||||
| const PostCSSSafeParser = require('postcss-safe-parser'); | |||||
| const SpriteLoaderPlugin = require('svg-sprite-loader/plugin'); | |||||
| const TerserPlugin = require('terser-webpack-plugin'); | |||||
| const VueLoaderPlugin = require('vue-loader/lib/plugin'); | |||||
| const {statSync} = require('fs'); | |||||
| const {resolve, parse} = require('path'); | |||||
| //const {SourceMapDevToolPlugin} = require('webpack'); | |||||
| const glob = (pattern) => fastGlob.sync(pattern, {cwd: __dirname, absolute: true}); | |||||
| const themes = {}; | |||||
| for (const path of glob('web_src/less/themes/*.less')) { | |||||
| themes[parse(path).name] = [path]; | |||||
| } | |||||
| const isProduction = process.env.NODE_ENV !== 'development'; | |||||
| module.exports = { | |||||
| mode: isProduction ? 'production' : 'development', | |||||
| entry: { | |||||
| index: [ | |||||
| resolve(__dirname, 'web_src/js/index.js'), | |||||
| resolve(__dirname, 'web_src/less/index.less'), | |||||
| ], | |||||
| swagger: [ | |||||
| resolve(__dirname, 'web_src/js/standalone/swagger.js'), | |||||
| ], | |||||
| jquery: [ | |||||
| resolve(__dirname, 'web_src/js/jquery.js'), | |||||
| ], | |||||
| icons: glob('node_modules/@primer/octicons/build/svg/**/*.svg'), | |||||
| ...themes, | |||||
| }, | |||||
| devtool: false, | |||||
| output: { | |||||
| path: resolve(__dirname, 'public'), | |||||
| filename: 'js/[name].js', | |||||
| chunkFilename: 'js/[name].js', | |||||
| }, | |||||
| node:{ | |||||
| fs: 'empty' | |||||
| }, | |||||
| optimization: { | |||||
| minimize: isProduction, | |||||
| minimizer: [ | |||||
| new TerserPlugin({ | |||||
| sourceMap: true, | |||||
| extractComments: false, | |||||
| terserOptions: { | |||||
| keep_fnames: /^(HTML|SVG)/, // https://github.com/fgnass/domino/issues/144 | |||||
| output: { | |||||
| comments: false, | |||||
| }, | |||||
| }, | |||||
| }), | |||||
| new OptimizeCSSAssetsPlugin({ | |||||
| cssProcessor: cssnano, | |||||
| cssProcessorOptions: { | |||||
| parser: PostCSSSafeParser, | |||||
| }, | |||||
| cssProcessorPluginOptions: { | |||||
| preset: [ | |||||
| 'default', | |||||
| { | |||||
| discardComments: { | |||||
| removeAll: true, | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| }), | |||||
| ], | |||||
| splitChunks: { | |||||
| chunks: 'async', | |||||
| name: (_, chunks) => chunks.map((item) => item.name).join('-'), | |||||
| cacheGroups: { | |||||
| // this bundles all monaco's languages into one file instead of emitting 1-65.js files | |||||
| monaco: { | |||||
| test: /monaco-editor/, | |||||
| name: 'monaco', | |||||
| chunks: 'async' | |||||
| } | |||||
| } | |||||
| } | |||||
| }, | |||||
| module: { | |||||
| rules: [ | |||||
| { | |||||
| test: /\.vue$/, | |||||
| exclude: /node_modules/, | |||||
| loader: 'vue-loader', | |||||
| }, | |||||
| { | |||||
| test: require.resolve('jquery-datetimepicker'), | |||||
| use: 'imports-loader?define=>false,exports=>false', | |||||
| }, | |||||
| { | |||||
| test: /\.worker\.js$/, | |||||
| exclude: /monaco/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'worker-loader', | |||||
| options: { | |||||
| name: '[name].js', | |||||
| inline: true, | |||||
| fallback: false, | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.ts$/, | |||||
| use: [ | |||||
| { | |||||
| loader: "ts-loader", | |||||
| } | |||||
| ], | |||||
| exclude: /node_modules/ | |||||
| }, | |||||
| { | |||||
| test: /\.js$/, | |||||
| exclude: /node_modules/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'babel-loader', | |||||
| options: { | |||||
| cacheDirectory: true, | |||||
| cacheCompression: false, | |||||
| cacheIdentifier: [ | |||||
| resolve(__dirname, 'package.json'), | |||||
| resolve(__dirname, 'package-lock.json'), | |||||
| resolve(__dirname, 'webpack.config.js'), | |||||
| ].map((path) => statSync(path).mtime.getTime()).join(':'), | |||||
| sourceMaps: true, | |||||
| presets: [ | |||||
| [ | |||||
| '@babel/preset-env', | |||||
| { | |||||
| useBuiltIns: 'usage', | |||||
| corejs: 3, | |||||
| }, | |||||
| ], | |||||
| ], | |||||
| plugins: [ | |||||
| [ | |||||
| '@babel/plugin-transform-runtime', | |||||
| { | |||||
| regenerator: true, | |||||
| } | |||||
| ], | |||||
| '@babel/plugin-proposal-object-rest-spread', | |||||
| ], | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.(less|css)$/i, | |||||
| use: [ | |||||
| { | |||||
| loader: MiniCssExtractPlugin.loader, | |||||
| }, | |||||
| { | |||||
| loader: 'css-loader', | |||||
| options: { | |||||
| importLoaders: 2, | |||||
| url: (_url, resourcePath) => { | |||||
| // only resolve URLs for dependencies | |||||
| return resourcePath.includes('node_modules'); | |||||
| }, | |||||
| } | |||||
| }, | |||||
| { | |||||
| loader: 'postcss-loader', | |||||
| options: { | |||||
| plugins: () => [ | |||||
| PostCSSPresetEnv(), | |||||
| ], | |||||
| }, | |||||
| }, | |||||
| { | |||||
| loader: 'less-loader', | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.svg$/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'svg-sprite-loader', | |||||
| options: { | |||||
| extract: true, | |||||
| spriteFilename: 'img/svg/icons.svg', | |||||
| symbolId: (path) => { | |||||
| const {name} = parse(path); | |||||
| if (/@primer[/\\]octicons/.test(path)) { | |||||
| return `octicon-${name}`; | |||||
| } | |||||
| return name; | |||||
| }, | |||||
| }, | |||||
| }, | |||||
| { | |||||
| loader: 'svgo-loader', | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| { | |||||
| test: /\.(ttf|woff2?)$/, | |||||
| use: [ | |||||
| { | |||||
| loader: 'file-loader', | |||||
| options: { | |||||
| name: '[name].[ext]', | |||||
| outputPath: 'fonts/', | |||||
| publicPath: (url) => `../fonts/${url}`, // seems required for monaco's font | |||||
| }, | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| ], | |||||
| }, | |||||
| plugins: [ | |||||
| new VueLoaderPlugin(), | |||||
| // avoid generating useless js output files for css- and svg-only chunks | |||||
| new FixStyleOnlyEntriesPlugin({ | |||||
| extensions: ['less', 'scss', 'css', 'svg'], | |||||
| silent: true, | |||||
| }), | |||||
| new MiniCssExtractPlugin({ | |||||
| filename: 'css/[name].css', | |||||
| chunkFilename: 'css/[name].css', | |||||
| }), | |||||
| //new SourceMapDevToolPlugin({ | |||||
| //filename: 'js/[name].js.map', | |||||
| //include: [ | |||||
| //'js/index.js', | |||||
| //], | |||||
| //}), | |||||
| new SpriteLoaderPlugin({ | |||||
| plainSprite: true, | |||||
| }), | |||||
| new MonacoWebpackPlugin({ | |||||
| filename: 'js/monaco-[name].worker.js', | |||||
| }) | |||||
| ], | |||||
| performance: { | |||||
| hints: false, | |||||
| maxEntrypointSize: Infinity, | |||||
| maxAssetSize: Infinity, | |||||
| }, | |||||
| resolve: { | |||||
| symlinks: false, | |||||
| alias: { | |||||
| vue$: 'vue/dist/vue.esm.js', // needed because vue's default export is the runtime only | |||||
| }, | |||||
| extensions: ['.tsx', '.ts', '.js'] | |||||
| }, | |||||
| watchOptions: { | |||||
| ignored: [ | |||||
| 'node_modules/**', | |||||
| ], | |||||
| }, | |||||
| stats: { | |||||
| children: false, | |||||
| }, | |||||
| }; | |||||