forked from Gitlink/forgeplus-react
Merge branch 'newVersion_forge' of http://gitea.trustie.net/jasder/forgeplus-react into newVersion_forge
# Conflicts: # src/forge/Order/order.js
This commit is contained in:
commit
5c1bd9118c
|
|
@ -1,24 +1,26 @@
|
|||
'use strict';
|
||||
"use strict";
|
||||
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
|
||||
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
||||
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
||||
const getClientEnvironment = require('./env');
|
||||
const paths = require('./paths');
|
||||
const autoprefixer = require("autoprefixer");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
|
||||
const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin");
|
||||
const WatchMissingNodeModulesPlugin = require("react-dev-utils/WatchMissingNodeModulesPlugin");
|
||||
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
|
||||
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
|
||||
|
||||
const publicPath = '/';
|
||||
const env = getClientEnvironment('/');
|
||||
const getClientEnvironment = require("./env");
|
||||
|
||||
const paths = require("./paths");
|
||||
|
||||
const publicPath = "/";
|
||||
const env = getClientEnvironment("/");
|
||||
|
||||
module.exports = {
|
||||
optimization: {
|
||||
splitChunks: {
|
||||
chunks: 'async',
|
||||
chunks: "async",
|
||||
// 大于30KB才单独分离成chunk
|
||||
minSize: 30000,
|
||||
maxAsyncRequests: 5,
|
||||
|
|
@ -30,24 +32,24 @@ module.exports = {
|
|||
reuseExistingChunk: true,
|
||||
},
|
||||
vendors: {
|
||||
name: 'vendors',
|
||||
name: "vendors",
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: -10,
|
||||
chunks: "all"
|
||||
}
|
||||
}
|
||||
chunks: "all",
|
||||
},
|
||||
},
|
||||
},
|
||||
runtimeChunk: true
|
||||
runtimeChunk: true,
|
||||
},
|
||||
mode: 'development',
|
||||
mode: "development",
|
||||
// 开启调试
|
||||
devtool: "source-map", // 开启调试
|
||||
devtool: "source-map", // 开启调试
|
||||
// These are the "entry points" to our application.
|
||||
// This means they will be the "root" imports that are included in JS bundle.
|
||||
// The first two entry points enable "hot" CSS and auto-refreshes for JS.
|
||||
entry: [
|
||||
// We ship a few polyfills by default:
|
||||
require.resolve('./polyfills'),
|
||||
require.resolve("./polyfills"),
|
||||
// Include an alternative client for WebpackDevServer. A client's job is to
|
||||
// connect to WebpackDevServer by a socket and get notified about changes.
|
||||
// When you save a file, the client will either apply hot updates (in case
|
||||
|
|
@ -58,7 +60,7 @@ module.exports = {
|
|||
// the line below with these two lines if you prefer the stock client:
|
||||
// require.resolve('webpack-dev-server/client') + '?/',
|
||||
// require.resolve('webpack/hot/dev-server'),
|
||||
require.resolve('react-dev-utils/webpackHotDevClient'),
|
||||
require.resolve("react-dev-utils/webpackHotDevClient"),
|
||||
// Finally, this is your app's code:
|
||||
paths.appIndexJs,
|
||||
// We include the app code last so that if there is a runtime error during
|
||||
|
|
@ -68,25 +70,25 @@ module.exports = {
|
|||
output: {
|
||||
// Add /* filename */ comments to generated require()s in the output.
|
||||
pathinfo: true,
|
||||
globalObject: 'this',
|
||||
globalObject: "this",
|
||||
// This does not produce a real file. It's just the virtual path that is
|
||||
// served by WebpackDevServer in development. This is the JS bundle
|
||||
// containing code from all our entry points, and the Webpack runtime.
|
||||
filename: 'static/js/bundle.js',
|
||||
filename: "static/js/bundle.js",
|
||||
// There are also additional JS chunk files if you use code splitting.
|
||||
chunkFilename: 'static/js/[name].chunk.js',
|
||||
chunkFilename: "static/js/[name].chunk.js",
|
||||
// This is the URL that app is served from. We use "/" in development.
|
||||
publicPath,
|
||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||
devtoolModuleFilenameTemplate: info =>
|
||||
path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
|
||||
devtoolModuleFilenameTemplate: (info) =>
|
||||
path.resolve(info.absoluteResourcePath).replace(/\\/g, "/"),
|
||||
},
|
||||
resolve: {
|
||||
// This allows you to set a fallback for where Webpack should look for modules.
|
||||
// We placed these paths second because we want `node_modules` to "win"
|
||||
// if there are any conflicts. This matches Node resolution mechanism.
|
||||
// https://github.com/facebookincubator/create-react-app/issues/253
|
||||
modules: ['node_modules', paths.appNodeModules].concat(
|
||||
modules: ["node_modules", paths.appNodeModules].concat(
|
||||
// It is guaranteed to exist because we tweak it in `env.js`
|
||||
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
|
||||
),
|
||||
|
|
@ -96,13 +98,12 @@ module.exports = {
|
|||
// https://github.com/facebookincubator/create-react-app/issues/290
|
||||
// `web` extension prefixes have been added for better support
|
||||
// for React Native Web.
|
||||
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
|
||||
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
|
||||
alias: {
|
||||
|
||||
"educoder": __dirname + "/../src/common/educoder.js",
|
||||
educoder: __dirname + "/../src/common/educoder.js",
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
'react-native': 'react-native-web',
|
||||
"react-native": "react-native-web",
|
||||
},
|
||||
plugins: [
|
||||
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||
|
|
@ -126,10 +127,10 @@ module.exports = {
|
|||
// A missing `test` is equivalent to a match.
|
||||
{
|
||||
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
|
||||
loader: require.resolve('url-loader'),
|
||||
loader: require.resolve("url-loader"),
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'static/media/[name].[hash:8].[ext]',
|
||||
name: "static/media/[name].[hash:8].[ext]",
|
||||
},
|
||||
},
|
||||
// Process JS with Babel.
|
||||
|
|
@ -137,19 +138,22 @@ module.exports = {
|
|||
test: /\.(js|jsx|mjs)$/,
|
||||
include: paths.appSrc,
|
||||
exclude: /node_modules/,
|
||||
loader: require.resolve('babel-loader'),
|
||||
loader: require.resolve("babel-loader"),
|
||||
options: {
|
||||
// This is a feature of `babel-loader` for webpack (not Babel itself).
|
||||
// It enables caching results in ./node_modules/.cache/babel-loader/
|
||||
// directory for faster rebuilds.
|
||||
cacheDirectory: true,
|
||||
"plugins": [
|
||||
["import", {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": "css"
|
||||
}]
|
||||
]
|
||||
plugins: [
|
||||
[
|
||||
"import",
|
||||
{
|
||||
libraryName: "antd",
|
||||
libraryDirectory: "es",
|
||||
style: "css",
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
// "postcss" loader applies autoprefixer to our CSS.
|
||||
|
|
@ -160,29 +164,29 @@ module.exports = {
|
|||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
require.resolve('style-loader'),
|
||||
require.resolve("style-loader"),
|
||||
{
|
||||
loader: require.resolve('css-loader'),
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve('postcss-loader'),
|
||||
loader: require.resolve("postcss-loader"),
|
||||
options: {
|
||||
// Necessary for external CSS imports to work
|
||||
// https://github.com/facebookincubator/create-react-app/issues/2677
|
||||
ident: 'postcss',
|
||||
ident: "postcss",
|
||||
plugins: () => [
|
||||
require('postcss-flexbugs-fixes'),
|
||||
require("postcss-flexbugs-fixes"),
|
||||
autoprefixer({
|
||||
browsers: [
|
||||
'>1%',
|
||||
'last 4 versions',
|
||||
'Firefox ESR',
|
||||
'not ie < 9', // React doesn't support IE8 anyway
|
||||
">1%",
|
||||
"last 4 versions",
|
||||
"Firefox ESR",
|
||||
"not ie < 9", // React doesn't support IE8 anyway
|
||||
],
|
||||
flexbox: 'no-2009',
|
||||
flexbox: "no-2009",
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
|
@ -192,7 +196,7 @@ module.exports = {
|
|||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
require.resolve('style-loader'),
|
||||
require.resolve("style-loader"),
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
|
|
@ -200,8 +204,8 @@ module.exports = {
|
|||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("sass-loader")
|
||||
}
|
||||
loader: require.resolve("sass-loader"),
|
||||
},
|
||||
],
|
||||
},
|
||||
// "file" loader makes sure those assets get served by WebpackDevServer.
|
||||
|
|
@ -215,9 +219,9 @@ module.exports = {
|
|||
// Also exclude `html` and `json` extensions so they get processed
|
||||
// by webpacks internal loaders.
|
||||
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
|
||||
loader: require.resolve('file-loader'),
|
||||
loader: require.resolve("file-loader"),
|
||||
options: {
|
||||
name: 'static/media/[name].[hash:8].[ext]',
|
||||
name: "static/media/[name].[hash:8].[ext]",
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
@ -261,17 +265,18 @@ module.exports = {
|
|||
// You can remove this if you don't use Moment.js:
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new MonacoWebpackPlugin({
|
||||
features: ['!gotoSymbol'],
|
||||
})
|
||||
features: ["coreCommands", "find"],
|
||||
languages: ['plaintext','apex', 'azcli', 'bat', 'clojure', 'coffee', 'cpp', 'csharp', 'csp', 'css', 'dockerfile', 'fsharp', 'go', 'handlebars', 'html', 'ini', 'java', 'javascript', 'json', 'less', 'lua', 'markdown', 'msdax', 'mysql', 'objective', 'perl', 'pgsql', 'php', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'r', 'razor', 'redis', 'redshift', 'ruby', 'rust', 'sb', 'scheme', 'scss', 'shell', 'solidity', 'sql', 'st', 'swift', 'typescript', 'vb', 'xml', 'yaml']
|
||||
}),
|
||||
],
|
||||
// Some libraries import Node modules but don't use them in the browser.
|
||||
// Tell Webpack to provide empty mocks for them so importing them works.
|
||||
node: {
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
child_process: 'empty',
|
||||
dgram: "empty",
|
||||
fs: "empty",
|
||||
net: "empty",
|
||||
tls: "empty",
|
||||
child_process: "empty",
|
||||
},
|
||||
// Turn off performance hints during development because we don't do any
|
||||
// splitting or minification in interest of speed. These warnings become
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
'use strict';
|
||||
const autoprefixer = require('autoprefixer');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const ManifestPlugin = require('webpack-manifest-plugin');
|
||||
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
|
||||
const eslintFormatter = require('react-dev-utils/eslintFormatter');
|
||||
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
||||
"use strict";
|
||||
const autoprefixer = require("autoprefixer");
|
||||
const path = require("path");
|
||||
const webpack = require("webpack");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const ManifestPlugin = require("webpack-manifest-plugin");
|
||||
const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin");
|
||||
const SWPrecacheWebpackPlugin = require("sw-precache-webpack-plugin");
|
||||
const eslintFormatter = require("react-dev-utils/eslintFormatter");
|
||||
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
|
||||
const MonacoWebpackPlugin = require("monaco-editor-webpack-plugin");
|
||||
|
||||
const TerserJSPlugin = require('terser-webpack-plugin');
|
||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||
const TerserJSPlugin = require("terser-webpack-plugin");
|
||||
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
|
||||
|
||||
const paths = require('./paths');
|
||||
const getClientEnvironment = require('./env');
|
||||
const paths = require("./paths");
|
||||
const getClientEnvironment = require("./env");
|
||||
|
||||
// Some apps do not use client-side routing with pushState.
|
||||
// For these, "homepage" can be set to "." to enable relative asset paths.
|
||||
let publicPath = '/react/build/';
|
||||
let publicPath = "/react/build/";
|
||||
// let nodeEnv = process.env.NODE_ENV
|
||||
// if (nodeEnv === 'testBuild') {
|
||||
// publicPath = 'https://testforgeplus.trustie.net/react/build/';
|
||||
|
|
@ -28,7 +28,7 @@ let publicPath = '/react/build/';
|
|||
// publicPath = 'https://forgeplus.trustie.net/react/build/';
|
||||
// }
|
||||
const publicUrl = publicPath.slice(0, -1);
|
||||
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
|
||||
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
|
||||
const env = getClientEnvironment(publicPath);
|
||||
|
||||
// This is the production configuration.
|
||||
|
|
@ -36,296 +36,301 @@ const env = getClientEnvironment(publicPath);
|
|||
// The development configuration is different and lives in a separate file.
|
||||
// 上线用的
|
||||
module.exports = {
|
||||
optimization: {
|
||||
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
|
||||
splitChunks: {
|
||||
chunks: 'async',
|
||||
// 大于30KB才单独分离成chunk
|
||||
minSize: 30000,
|
||||
maxAsyncRequests: 5,
|
||||
maxInitialRequests: 3,
|
||||
name: true,
|
||||
cacheGroups: {
|
||||
default: {
|
||||
minChunks: 2,
|
||||
priority: -20,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// vendors: {
|
||||
// name: 'vendors',
|
||||
// test: /[\\/]node_modules[\\/]/,
|
||||
// priority: -10,
|
||||
// chunks: "all"
|
||||
// }
|
||||
}
|
||||
},
|
||||
runtimeChunk: true
|
||||
},
|
||||
bail: true,
|
||||
mode: 'production',
|
||||
devtool: false,//测试版
|
||||
entry: [require.resolve('./polyfills'), paths.appIndexJs],
|
||||
output: {
|
||||
path: paths.appBuild,
|
||||
globalObject: 'this',
|
||||
filename: './static/js/[name].[contenthash:8].js',
|
||||
chunkFilename: './static/js/[name].[contenthash:8].chunk.js',
|
||||
publicPath,
|
||||
optimization: {
|
||||
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
|
||||
splitChunks: {
|
||||
chunks: "async",
|
||||
// 大于30KB才单独分离成chunk
|
||||
minSize: 30000,
|
||||
maxAsyncRequests: 5,
|
||||
maxInitialRequests: 3,
|
||||
name: true,
|
||||
cacheGroups: {
|
||||
default: {
|
||||
minChunks: 2,
|
||||
priority: -20,
|
||||
reuseExistingChunk: true,
|
||||
},
|
||||
// vendors: {
|
||||
// name: 'vendors',
|
||||
// test: /[\\/]node_modules[\\/]/,
|
||||
// priority: -10,
|
||||
// chunks: "all"
|
||||
// }
|
||||
},
|
||||
},
|
||||
runtimeChunk: true,
|
||||
},
|
||||
bail: true,
|
||||
mode: "production",
|
||||
devtool: false, //测试版
|
||||
entry: [require.resolve("./polyfills"), paths.appIndexJs],
|
||||
output: {
|
||||
path: paths.appBuild,
|
||||
globalObject: "this",
|
||||
filename: "./static/js/[name].[contenthash:8].js",
|
||||
chunkFilename: "./static/js/[name].[contenthash:8].chunk.js",
|
||||
publicPath,
|
||||
|
||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||
devtoolModuleFilenameTemplate: info =>
|
||||
path
|
||||
.relative(paths.appSrc, info.absoluteResourcePath)
|
||||
.replace(/\\/g, '/'),
|
||||
},
|
||||
resolve: {
|
||||
// This allows you to set a fallback for where Webpack should look for modules.
|
||||
// We placed these paths second because we want `node_modules` to "win"
|
||||
// if there are any conflicts. This matches Node resolution mechanism.
|
||||
// https://github.com/facebookincubator/create-react-app/issues/253
|
||||
modules: ['node_modules', paths.appNodeModules].concat(
|
||||
// It is guaranteed to exist because we tweak it in `env.js`
|
||||
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
|
||||
),
|
||||
// These are the reasonable defaults supported by the Node ecosystem.
|
||||
// We also include JSX as a common component filename extension to support
|
||||
// some tools, although we do not recommend using it, see:
|
||||
// https://github.com/facebookincubator/create-react-app/issues/290
|
||||
// `web` extension prefixes have been added for better support
|
||||
// for React Native Web.
|
||||
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx'],
|
||||
alias: {
|
||||
"educoder": __dirname + "/../src/common/educoder.js",
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
'react-native': 'react-native-web',
|
||||
},
|
||||
plugins: [
|
||||
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||
// This often causes confusion because we only process files within src/ with babel.
|
||||
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
|
||||
// please link the files into your node_modules/ and let module-resolution kick in.
|
||||
// Make sure your source files are compiled, as they will not be processed in any way.
|
||||
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
|
||||
],
|
||||
},
|
||||
module: {
|
||||
strictExportPresence: true,
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|mjs)$/,
|
||||
enforce: 'pre',
|
||||
use: [
|
||||
{
|
||||
options: {
|
||||
formatter: eslintFormatter,
|
||||
eslintPath: require.resolve('eslint'),
|
||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||
devtoolModuleFilenameTemplate: (info) =>
|
||||
path
|
||||
.relative(paths.appSrc, info.absoluteResourcePath)
|
||||
.replace(/\\/g, "/"),
|
||||
},
|
||||
resolve: {
|
||||
// This allows you to set a fallback for where Webpack should look for modules.
|
||||
// We placed these paths second because we want `node_modules` to "win"
|
||||
// if there are any conflicts. This matches Node resolution mechanism.
|
||||
// https://github.com/facebookincubator/create-react-app/issues/253
|
||||
modules: ["node_modules", paths.appNodeModules].concat(
|
||||
// It is guaranteed to exist because we tweak it in `env.js`
|
||||
process.env.NODE_PATH.split(path.delimiter).filter(Boolean)
|
||||
),
|
||||
// These are the reasonable defaults supported by the Node ecosystem.
|
||||
// We also include JSX as a common component filename extension to support
|
||||
// some tools, although we do not recommend using it, see:
|
||||
// https://github.com/facebookincubator/create-react-app/issues/290
|
||||
// `web` extension prefixes have been added for better support
|
||||
// for React Native Web.
|
||||
extensions: [".web.js", ".mjs", ".js", ".json", ".web.jsx", ".jsx"],
|
||||
alias: {
|
||||
educoder: __dirname + "/../src/common/educoder.js",
|
||||
// Support React Native Web
|
||||
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
|
||||
"react-native": "react-native-web",
|
||||
},
|
||||
plugins: [
|
||||
// Prevents users from importing files from outside of src/ (or node_modules/).
|
||||
// This often causes confusion because we only process files within src/ with babel.
|
||||
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
|
||||
// please link the files into your node_modules/ and let module-resolution kick in.
|
||||
// Make sure your source files are compiled, as they will not be processed in any way.
|
||||
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
|
||||
],
|
||||
},
|
||||
module: {
|
||||
strictExportPresence: true,
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx|mjs)$/,
|
||||
enforce: "pre",
|
||||
use: [
|
||||
{
|
||||
options: {
|
||||
formatter: eslintFormatter,
|
||||
eslintPath: require.resolve("eslint"),
|
||||
},
|
||||
loader: require.resolve("eslint-loader"),
|
||||
},
|
||||
],
|
||||
include: paths.appSrc,
|
||||
},
|
||||
{
|
||||
// "oneOf" will traverse all following loaders until one will
|
||||
// match the requirements. When no loader matches it will fall
|
||||
// back to the "file" loader at the end of the loader list.
|
||||
oneOf: [
|
||||
// "url" loader works just like "file" loader but it also embeds
|
||||
// assets smaller than specified size as data URLs to avoid requests.
|
||||
{
|
||||
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
|
||||
loader: require.resolve("url-loader"),
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: "static/media/[name].[hash:8].[ext]",
|
||||
},
|
||||
},
|
||||
// Process JS with Babel.
|
||||
{
|
||||
test: /\.(js|jsx|mjs)$/,
|
||||
include: paths.appSrc,
|
||||
exclude: /node_modules/,
|
||||
loader: require.resolve("babel-loader"),
|
||||
options: {
|
||||
compact: true,
|
||||
plugins: [
|
||||
[
|
||||
"import",
|
||||
{
|
||||
libraryName: "antd",
|
||||
libraryDirectory: "es",
|
||||
style: "css",
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
loader: require.resolve('eslint-loader'),
|
||||
},
|
||||
],
|
||||
include: paths.appSrc,
|
||||
},
|
||||
{
|
||||
// "oneOf" will traverse all following loaders until one will
|
||||
// match the requirements. When no loader matches it will fall
|
||||
// back to the "file" loader at the end of the loader list.
|
||||
oneOf: [
|
||||
// "url" loader works just like "file" loader but it also embeds
|
||||
// assets smaller than specified size as data URLs to avoid requests.
|
||||
{
|
||||
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
|
||||
loader: require.resolve('url-loader'),
|
||||
options: {
|
||||
limit: 10000,
|
||||
name: 'static/media/[name].[hash:8].[ext]',
|
||||
},
|
||||
},
|
||||
// Process JS with Babel.
|
||||
{
|
||||
test: /\.(js|jsx|mjs)$/,
|
||||
include: paths.appSrc,
|
||||
exclude: /node_modules/,
|
||||
loader: require.resolve('babel-loader'),
|
||||
options: {
|
||||
compact: true,
|
||||
"plugins": [
|
||||
["import", {
|
||||
"libraryName": "antd",
|
||||
"libraryDirectory": "es",
|
||||
"style": "css"
|
||||
}]
|
||||
]
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
sourceMap: shouldUseSourceMap,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("postcss-loader"),
|
||||
options: {
|
||||
ident: "postcss",
|
||||
plugins: () => [
|
||||
require("postcss-flexbugs-fixes"),
|
||||
autoprefixer({
|
||||
browsers: [
|
||||
">1%",
|
||||
"last 4 versions",
|
||||
"Firefox ESR",
|
||||
"not ie < 9", // React doesn't support IE8 anyway
|
||||
],
|
||||
flexbox: "no-2009",
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [
|
||||
{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
sourceMap: shouldUseSourceMap,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("sass-loader"),
|
||||
},
|
||||
],
|
||||
},
|
||||
// "file" loader makes sure assets end up in the `build` folder.
|
||||
// When you `import` an asset, you get its filename.
|
||||
// This loader doesn't use a "test" so it will catch all modules
|
||||
// that fall through the other loaders.
|
||||
{
|
||||
loader: require.resolve("file-loader"),
|
||||
// Exclude `js` files to keep "css" loader working as it injects
|
||||
// it's runtime that would otherwise processed through "file" loader.
|
||||
// Also exclude `html` and `json` extensions so they get processed
|
||||
// by webpacks internal loaders.
|
||||
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
|
||||
options: {
|
||||
name: "static/media/[name].[contenthash:8].[ext]",
|
||||
},
|
||||
},
|
||||
// ** STOP ** Are you adding a new loader?
|
||||
// Make sure to add the new loader(s) before the "file" loader.
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
// Makes some environment variables available in index.html.
|
||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
// In production, it will be an empty string unless you specify "homepage"
|
||||
// in `package.json`, in which case it will be the pathname of that URL.
|
||||
// Generates an `index.html` file with the <script> injected.
|
||||
new HtmlWebpackPlugin({
|
||||
inject: false,
|
||||
template: paths.appHtml,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeRedundantAttributes: true,
|
||||
useShortDoctype: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
keepClosingSlash: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
minifyURLs: true,
|
||||
},
|
||||
}),
|
||||
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
|
||||
// Makes some environment variables available to the JS code, for example:
|
||||
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
|
||||
// It is absolutely essential that NODE_ENV was set to production here.
|
||||
// Otherwise React will be compiled in the very slow development mode.
|
||||
new webpack.DefinePlugin(env.stringified),
|
||||
|
||||
use: [{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
sourceMap: shouldUseSourceMap,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve('postcss-loader'),
|
||||
options: {
|
||||
ident: 'postcss',
|
||||
plugins: () => [
|
||||
require('postcss-flexbugs-fixes'),
|
||||
autoprefixer({
|
||||
browsers: [
|
||||
'>1%',
|
||||
'last 4 versions',
|
||||
'Firefox ESR',
|
||||
'not ie < 9', // React doesn't support IE8 anyway
|
||||
],
|
||||
flexbox: 'no-2009',
|
||||
}),
|
||||
],
|
||||
},
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: [{
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: {
|
||||
publicPath
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("css-loader"),
|
||||
options: {
|
||||
importLoaders: 1,
|
||||
sourceMap: shouldUseSourceMap,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: require.resolve("sass-loader")
|
||||
}
|
||||
],
|
||||
},
|
||||
// "file" loader makes sure assets end up in the `build` folder.
|
||||
// When you `import` an asset, you get its filename.
|
||||
// This loader doesn't use a "test" so it will catch all modules
|
||||
// that fall through the other loaders.
|
||||
{
|
||||
loader: require.resolve('file-loader'),
|
||||
// Exclude `js` files to keep "css" loader working as it injects
|
||||
// it's runtime that would otherwise processed through "file" loader.
|
||||
// Also exclude `html` and `json` extensions so they get processed
|
||||
// by webpacks internal loaders.
|
||||
exclude: [/\.(js|jsx|mjs)$/, /\.html$/, /\.json$/],
|
||||
options: {
|
||||
name: 'static/media/[name].[contenthash:8].[ext]',
|
||||
},
|
||||
},
|
||||
// ** STOP ** Are you adding a new loader?
|
||||
// Make sure to add the new loader(s) before the "file" loader.
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
// Makes some environment variables available in index.html.
|
||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
// In production, it will be an empty string unless you specify "homepage"
|
||||
// in `package.json`, in which case it will be the pathname of that URL.
|
||||
// Generates an `index.html` file with the <script> injected.
|
||||
new HtmlWebpackPlugin({
|
||||
inject: false,
|
||||
template: paths.appHtml,
|
||||
minify: {
|
||||
removeComments: true,
|
||||
collapseWhitespace: true,
|
||||
removeRedundantAttributes: true,
|
||||
useShortDoctype: true,
|
||||
removeEmptyAttributes: true,
|
||||
removeStyleLinkTypeAttributes: true,
|
||||
keepClosingSlash: true,
|
||||
minifyJS: true,
|
||||
minifyCSS: true,
|
||||
minifyURLs: true,
|
||||
},
|
||||
}),
|
||||
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
|
||||
// Makes some environment variables available to the JS code, for example:
|
||||
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
|
||||
// It is absolutely essential that NODE_ENV was set to production here.
|
||||
// Otherwise React will be compiled in the very slow development mode.
|
||||
new webpack.DefinePlugin(env.stringified),
|
||||
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'static/css/[name].[contenthash:8].css',
|
||||
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
|
||||
}),
|
||||
// Generate a manifest file which contains a mapping of all asset filenames
|
||||
// to their corresponding output file so that tools can pick it up without
|
||||
// having to parse `index.html`.
|
||||
new ManifestPlugin({
|
||||
fileName: 'asset-manifest.json',
|
||||
}),
|
||||
// Generate a service worker script that will precache, and keep up to date,
|
||||
// the HTML & assets that are part of the Webpack build.
|
||||
new SWPrecacheWebpackPlugin({
|
||||
// By default, a cache-busting query parameter is appended to requests
|
||||
// used to populate the caches, to ensure the responses are fresh.
|
||||
// If a URL is already hashed by Webpack, then there is no concern
|
||||
// about it being stale, and the cache-busting can be skipped.
|
||||
dontCacheBustUrlsMatching: /\.\w{8}\./,
|
||||
filename: 'service-worker.js',
|
||||
logger(message) {
|
||||
if (message.indexOf('Total precache size is') === 0) {
|
||||
// This message occurs for every build and is a bit too noisy.
|
||||
return;
|
||||
}
|
||||
if (message.indexOf('Skipping static resource') === 0) {
|
||||
// This message obscures real errors so we ignore it.
|
||||
// https://github.com/facebookincubator/create-react-app/issues/2612
|
||||
return;
|
||||
}
|
||||
// console.log(message);
|
||||
},
|
||||
minify: true,
|
||||
// For unknown URLs, fallback to the index page
|
||||
navigateFallback: publicUrl + '/index.html',
|
||||
// Ignores URLs starting from /__ (useful for Firebase):
|
||||
// https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
|
||||
navigateFallbackWhitelist: [/^(?!\/__).*/],
|
||||
// Don't precache sourcemaps (they're large) and build asset manifest:
|
||||
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
|
||||
}),
|
||||
// Moment.js is an extremely popular library that bundles large locale files
|
||||
// by default due to how Webpack interprets its code. This is a practical
|
||||
// solution that requires the user to opt into importing specific locales.
|
||||
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
||||
// You can remove this if you don't use Moment.js:
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new MonacoWebpackPlugin({
|
||||
features: ['!gotoSymbol'],
|
||||
}),
|
||||
new webpack.NamedChunksPlugin(),
|
||||
new webpack.HashedModuleIdsPlugin()
|
||||
],
|
||||
// Some libraries import Node modules but don't use them in the browser.
|
||||
// Tell Webpack to provide empty mocks for them so importing them works.
|
||||
node: {
|
||||
dgram: 'empty',
|
||||
fs: 'empty',
|
||||
net: 'empty',
|
||||
tls: 'empty',
|
||||
child_process: 'empty',
|
||||
},
|
||||
new MiniCssExtractPlugin({
|
||||
filename: "static/css/[name].[contenthash:8].css",
|
||||
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
|
||||
}),
|
||||
// Generate a manifest file which contains a mapping of all asset filenames
|
||||
// to their corresponding output file so that tools can pick it up without
|
||||
// having to parse `index.html`.
|
||||
new ManifestPlugin({
|
||||
fileName: "asset-manifest.json",
|
||||
}),
|
||||
// Generate a service worker script that will precache, and keep up to date,
|
||||
// the HTML & assets that are part of the Webpack build.
|
||||
new SWPrecacheWebpackPlugin({
|
||||
// By default, a cache-busting query parameter is appended to requests
|
||||
// used to populate the caches, to ensure the responses are fresh.
|
||||
// If a URL is already hashed by Webpack, then there is no concern
|
||||
// about it being stale, and the cache-busting can be skipped.
|
||||
dontCacheBustUrlsMatching: /\.\w{8}\./,
|
||||
filename: "service-worker.js",
|
||||
logger(message) {
|
||||
if (message.indexOf("Total precache size is") === 0) {
|
||||
// This message occurs for every build and is a bit too noisy.
|
||||
return;
|
||||
}
|
||||
if (message.indexOf("Skipping static resource") === 0) {
|
||||
// This message obscures real errors so we ignore it.
|
||||
// https://github.com/facebookincubator/create-react-app/issues/2612
|
||||
return;
|
||||
}
|
||||
// console.log(message);
|
||||
},
|
||||
minify: true,
|
||||
// For unknown URLs, fallback to the index page
|
||||
navigateFallback: publicUrl + "/index.html",
|
||||
// Ignores URLs starting from /__ (useful for Firebase):
|
||||
// https://github.com/facebookincubator/create-react-app/issues/2237#issuecomment-302693219
|
||||
navigateFallbackWhitelist: [/^(?!\/__).*/],
|
||||
// Don't precache sourcemaps (they're large) and build asset manifest:
|
||||
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
|
||||
}),
|
||||
// Moment.js is an extremely popular library that bundles large locale files
|
||||
// by default due to how Webpack interprets its code. This is a practical
|
||||
// solution that requires the user to opt into importing specific locales.
|
||||
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
||||
// You can remove this if you don't use Moment.js:
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
new MonacoWebpackPlugin({
|
||||
features: ["coreCommands", "find"],
|
||||
languages: ['plaintext','apex', 'azcli', 'bat', 'clojure', 'coffee', 'cpp', 'csharp', 'csp', 'css', 'dockerfile', 'fsharp', 'go', 'handlebars', 'html', 'ini', 'java', 'javascript', 'json', 'less', 'lua', 'markdown', 'msdax', 'mysql', 'objective', 'perl', 'pgsql', 'php', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'r', 'razor', 'redis', 'redshift', 'ruby', 'rust', 'sb', 'scheme', 'scss', 'shell', 'solidity', 'sql', 'st', 'swift', 'typescript', 'vb', 'xml', 'yaml']
|
||||
}),
|
||||
new webpack.NamedChunksPlugin(),
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
],
|
||||
// Some libraries import Node modules but don't use them in the browser.
|
||||
// Tell Webpack to provide empty mocks for them so importing them works.
|
||||
node: {
|
||||
dgram: "empty",
|
||||
fs: "empty",
|
||||
net: "empty",
|
||||
tls: "empty",
|
||||
child_process: "empty",
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -14904,20 +14904,13 @@
|
|||
}
|
||||
},
|
||||
"react-monaco-editor": {
|
||||
"version": "0.25.1",
|
||||
"resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.25.1.tgz",
|
||||
"integrity": "sha512-VLksQjt8fmeIZoET9fQgmR0sdCCBFaiss92MwW5JvgO3JfrnhHtrLBqrSQRjtbUmef1EmEKi4gZp5Mh0oidvVg==",
|
||||
"version": "0.36.0",
|
||||
"resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.36.0.tgz",
|
||||
"integrity": "sha512-JVA5SZhOoYZ0DCdTwYgagtRb3jHo4KN7TVFiJauG+ZBAJWfDSTzavPIrwzWbgu8ahhDqDk4jUcYlOJL2BC/0UA==",
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"monaco-editor": "^0.16.0",
|
||||
"@types/react": "^16.x",
|
||||
"monaco-editor": "*",
|
||||
"prop-types": "^15.7.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"monaco-editor": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.16.2.tgz",
|
||||
"integrity": "sha512-NtGrFzf54jADe7qsWh3lazhS7Kj0XHkJUGBq9fA/Jbwc+sgVcyfsYF6z2AQ7hPqDC+JmdOt/OwFjBnRwqXtx6w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-onclickoutside": {
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@
|
|||
"katex": "^0.11.1",
|
||||
"lodash": "^4.17.15",
|
||||
"loglevel": "^1.6.8",
|
||||
"material-ui": "^1.0.0-beta.40",
|
||||
"marked": "^1.0.0",
|
||||
"material-ui": "^1.0.0-beta.40",
|
||||
"md5": "^2.2.1",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"moment": "^2.23.0",
|
||||
|
|
@ -72,10 +72,10 @@
|
|||
"rc-tree": "^1.15.3",
|
||||
"rc-upload": "^2.9.4",
|
||||
"react": "^16.13.1",
|
||||
"react-color": "^2.18.0",
|
||||
"react-beautiful-dnd": "^10.0.4",
|
||||
"react-codemirror": "^1.0.0",
|
||||
"react-codemirror2": "^6.0.1",
|
||||
"react-color": "^2.18.0",
|
||||
"react-content-loader": "^3.1.1",
|
||||
"react-cookies": "^0.1.1",
|
||||
"react-datepicker": "^2.14.1",
|
||||
|
|
@ -84,7 +84,7 @@
|
|||
"react-hot-loader": "^4.12.20",
|
||||
"react-infinite-scroller": "^1.2.4",
|
||||
"react-loadable": "^5.3.1",
|
||||
"react-monaco-editor": "^0.25.1",
|
||||
"react-monaco-editor": "0.36",
|
||||
"react-player": "^1.15.3",
|
||||
"react-redux": "5.0.7",
|
||||
"react-router": "^4.2.0",
|
||||
|
|
@ -194,4 +194,4 @@
|
|||
"webpack": "^4.42.1",
|
||||
"webpack-bundle-analyzer": "^3.7.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,9 +98,9 @@ export function initAxiosInterceptors(props) {
|
|||
|
||||
// TODO 避免重复的请求 https://github.com/axios/axios#cancellation
|
||||
// TODO 读取到package.json中的配置?
|
||||
var proxy = "http://localhost:3000"
|
||||
proxy = "https://pre-newweb.educoder.net"
|
||||
proxy = "https://testforgeplus.trustie.net/"
|
||||
// var proxy = "http://localhost:3000"
|
||||
// proxy = "https://pre-newweb.educoder.net"
|
||||
var proxy = "https://testforgeplus.trustie.net/"
|
||||
|
||||
// 在这里使用requestMap控制,避免用户通过双击等操作发出重复的请求;
|
||||
// 如果需要支持重复的请求,考虑config里面自定义一个allowRepeat参考来控制
|
||||
|
|
|
|||
|
|
@ -344,7 +344,7 @@ class CoderRootDirectory extends Component{
|
|||
return(
|
||||
<Spin spinning={isSpin}>
|
||||
<div className="main">
|
||||
<div className="f-wrap-between">
|
||||
<div className="f-wrap-between mb20">
|
||||
<div className="f-wrap-alignCenter">
|
||||
<SelectBranch branch={branch} changeBranch={this.changeBranch} {...this.props} {...this.state}></SelectBranch>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,159 +1,243 @@
|
|||
import React , { Component } from "react";
|
||||
import { Popconfirm } from 'antd';
|
||||
import './list.css';
|
||||
import axios from 'axios';
|
||||
|
||||
import CodeMirror from 'react-codemirror';
|
||||
require('codemirror/lib/codemirror.css');
|
||||
require('codemirror/mode/javascript/javascript');
|
||||
require('codemirror/mode/xml/xml');
|
||||
require('codemirror/mode/markdown/markdown');
|
||||
import React, { Component } from "react";
|
||||
import { Popconfirm, Select } from "antd";
|
||||
import "./list.css";
|
||||
import axios from "axios";
|
||||
import Meditor from "../Newfile/m_editor";
|
||||
|
||||
function bytesToSize(bytes) {
|
||||
if (bytes === 0) return '0 B';
|
||||
if (bytes === 0) return "0 B";
|
||||
let k = 1024,
|
||||
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
|
||||
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return (bytes / Math.pow(k, i)). toFixed(2) + ' ' + sizes[i];
|
||||
sizes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"],
|
||||
i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return (bytes / Math.pow(k, i)).toFixed(2) + " " + sizes[i];
|
||||
}
|
||||
class CoderRootFileDetail extends Component{
|
||||
constructor(props){
|
||||
class CoderRootFileDetail extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
readOnly:true,
|
||||
value:undefined
|
||||
}
|
||||
this.state = {
|
||||
readOnly: true,
|
||||
value: undefined,
|
||||
language: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
componentDidMount = () => {
|
||||
const { detail, readOnly } = this.props;
|
||||
|
||||
this.setState({
|
||||
value: detail.content,
|
||||
readOnly: readOnly
|
||||
})
|
||||
}
|
||||
|
||||
EditFile=()=>{
|
||||
readOnly: readOnly,
|
||||
});
|
||||
};
|
||||
select_language = (e) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
readOnly:false
|
||||
})
|
||||
}
|
||||
CancelEdit=()=>{
|
||||
language: e,
|
||||
});
|
||||
};
|
||||
EditFile = () => {
|
||||
this.setState({
|
||||
readOnly:true
|
||||
})
|
||||
}
|
||||
readOnly: false,
|
||||
});
|
||||
};
|
||||
CancelEdit = () => {
|
||||
this.setState({
|
||||
readOnly: true,
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑文件
|
||||
|
||||
changeMmirror=(e,e1,value)=>{
|
||||
changeMmirror = (e, e1, value) => {
|
||||
this.setState({
|
||||
value
|
||||
})
|
||||
}
|
||||
value,
|
||||
});
|
||||
};
|
||||
|
||||
deleteFile=()=>{
|
||||
const { branch , detail }= this.props;
|
||||
deleteFile = () => {
|
||||
const { branch, detail } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
|
||||
const url = `/repositories/${projectsId}/delete_file.json`;
|
||||
axios.delete(url,{
|
||||
params:{
|
||||
filepath:detail.path,
|
||||
branch,
|
||||
sha:detail.sha
|
||||
}
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification("删除成功!");
|
||||
this.props.history.push(`/projects/${projectsId}`);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
const url = `/repositories/${projectsId}/delete_file.json`;
|
||||
axios
|
||||
.delete(url, {
|
||||
params: {
|
||||
filepath: detail.path,
|
||||
branch,
|
||||
sha: detail.sha,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.showNotification("删除成功!");
|
||||
this.props.history.push(`/projects/${projectsId}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
// // 确认修改文件
|
||||
// UpdateFile=()=>{
|
||||
// const { branch , detail}= this.props;
|
||||
// const { projectsId } = this.props.match.params;
|
||||
// const { value } = this.state;
|
||||
// const url =`/repositories/${projectsId}/update_file.json`;
|
||||
// axios.put(url,{
|
||||
// filepath:detail.path,
|
||||
// branch,
|
||||
// content:value,
|
||||
// sha:detail.sha,
|
||||
// }).then(result=>{
|
||||
// if(result){
|
||||
// this.props.showNotification("修改成功!");
|
||||
// this.setState({
|
||||
// readOnly:true
|
||||
// })
|
||||
// }
|
||||
// }).catch(error=>{
|
||||
// console.log(error);
|
||||
// })
|
||||
// }
|
||||
updateCode = (value) => {
|
||||
this.setState({
|
||||
value,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// 确认修改文件
|
||||
UpdateFile=()=>{
|
||||
const { branch , detail}= this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { value } = this.state;
|
||||
const url =`/repositories/${projectsId}/update_file.json`;
|
||||
axios.put(url,{
|
||||
filepath:detail.path,
|
||||
branch,
|
||||
content:value,
|
||||
sha:detail.sha,
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.showNotification("修改成功!");
|
||||
this.setState({
|
||||
readOnly:true
|
||||
})
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
updateCode=(value)=> {
|
||||
this.setState({
|
||||
value,
|
||||
});
|
||||
}
|
||||
|
||||
render(){
|
||||
const { detail , current_user , isManager , isDeveloper } = this.props;
|
||||
const { readOnly } = this.state;
|
||||
render() {
|
||||
const { detail, current_user, isManager, isDeveloper } = this.props;
|
||||
const { readOnly, language } = this.state;
|
||||
let flag = current_user && current_user.login && (isManager || isDeveloper);
|
||||
var options = {
|
||||
lineNumbers: true,
|
||||
mode: 'javascript',
|
||||
readOnly:readOnly?'nocursor':false,
|
||||
autofocus:readOnly?false:true,
|
||||
styleActiveLine:true
|
||||
};
|
||||
return(
|
||||
<div>
|
||||
<div className="branchTable">
|
||||
<p className="branchTitle f-wrap-alignCenter f-wrap-between">
|
||||
<span>{bytesToSize(detail && detail.size)}</span>
|
||||
{
|
||||
flag &&
|
||||
<span>
|
||||
{
|
||||
readOnly ?
|
||||
<a onClick={this.EditFile} className="ml20"><i className="iconfont icon-bianji font-15 color-grey-6"></i></a>
|
||||
:
|
||||
<React.Fragment>
|
||||
<button type="button" className="ant-btn ant-btn-sm mr10" onClick={this.CancelEdit}><span>取 消</span>
|
||||
</button>
|
||||
<button type="button" className="ant-btn ant-btn-primary ant-btn-sm" onClick={this.UpdateFile}><span>确 定</span>
|
||||
</button>
|
||||
</React.Fragment>
|
||||
}
|
||||
const Option = Select.Option;
|
||||
const languages = [
|
||||
"apex",
|
||||
"azcli",
|
||||
"bat",
|
||||
"clojure",
|
||||
"coffee",
|
||||
"cpp",
|
||||
"csharp",
|
||||
"csp",
|
||||
"css",
|
||||
"dockerfile",
|
||||
"fsharp",
|
||||
"go",
|
||||
"handlebars",
|
||||
"html",
|
||||
"ini",
|
||||
"java",
|
||||
"javascript",
|
||||
"json",
|
||||
"less",
|
||||
"lua",
|
||||
"markdown",
|
||||
"msdax",
|
||||
"mysql",
|
||||
"objective",
|
||||
"perl",
|
||||
"pgsql",
|
||||
"php",
|
||||
"postiats",
|
||||
"powerquery",
|
||||
"powershell",
|
||||
"pug",
|
||||
"python",
|
||||
"r",
|
||||
"razor",
|
||||
"redis",
|
||||
"redshift",
|
||||
"ruby",
|
||||
"rust",
|
||||
"sb",
|
||||
"scheme",
|
||||
"scss",
|
||||
"shell",
|
||||
"solidity",
|
||||
"sql",
|
||||
"st",
|
||||
"swift",
|
||||
"typescript",
|
||||
"vb",
|
||||
"xml",
|
||||
"yaml",
|
||||
];
|
||||
return (
|
||||
<div className="mb20">
|
||||
<div className="grid-item branchTitle">
|
||||
<div className="grid-item">
|
||||
<span className="ml20 color-grey-6 font-16">{bytesToSize(detail && detail.size)}</span>
|
||||
</div>
|
||||
<p className="text-right">
|
||||
{flag && (
|
||||
<div>
|
||||
{readOnly ? (
|
||||
<a onClick={this.EditFile} className="ml20">
|
||||
<i className="iconfont icon-bianji1 font-15 color-grey-6"></i>
|
||||
</a>
|
||||
) : (
|
||||
<React.Fragment>
|
||||
<Select
|
||||
showSearch={true}
|
||||
placeholder={"请选择文本语言"}
|
||||
style={{ width: 200 }}
|
||||
value={language}
|
||||
onChange={this.select_language}
|
||||
>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages.map((item, key) => {
|
||||
return <Option value={item}>{item}</Option>;
|
||||
})}
|
||||
</Select>
|
||||
<button
|
||||
type="button"
|
||||
className="ant-btn ant-btn-sm ml20"
|
||||
onClick={this.CancelEdit}
|
||||
>
|
||||
<span>取 消</span>
|
||||
</button>
|
||||
{/* <button type="button" className="ant-btn ant-btn-primary ant-btn-sm" onClick={this.UpdateFile}><span>确 定</span>
|
||||
</button> */}
|
||||
</React.Fragment>
|
||||
)}
|
||||
|
||||
<Popconfirm title="确认删除这个文件?" className="ml20" okText="确定" cancelText="取消" onConfirm={this.deleteFile}>
|
||||
<a><i className="iconfont icon-shanchu font-15 color-grey-6"></i></a>
|
||||
<Popconfirm
|
||||
title="确认删除这个文件?"
|
||||
className="ml20"
|
||||
okText="确定"
|
||||
cancelText="取消"
|
||||
onConfirm={this.deleteFile}
|
||||
>
|
||||
<a>
|
||||
<i className="iconfont icon-shanchu font-15 color-grey-6"></i>
|
||||
</a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
<div className={readOnly ? "content-file" :"content-file edit"}>
|
||||
{
|
||||
detail.direct_download ?
|
||||
<div className="text-center">
|
||||
<a href={detail.download_url} className="color-blue font-15">下载原始文件</a>
|
||||
</div>
|
||||
:
|
||||
<CodeMirror ref="editor" value={detail.content} onChange={this.updateCode} options={options} />
|
||||
}
|
||||
<div>
|
||||
{detail.direct_download ? (
|
||||
<div className="text-center">
|
||||
<a href={detail.download_url} className="color-blue font-15">
|
||||
下载原始文件
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<Meditor
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
language={language ? language : "javascript"}
|
||||
filepath={`/${detail.path}`}
|
||||
content={detail.content}
|
||||
readOnly={readOnly}
|
||||
editorType="update"
|
||||
></Meditor>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class DetailTop extends Component {
|
|||
</Link> */}
|
||||
<a href="javscript:void(0)" style={{cursor:"default"}}>
|
||||
<i className="iconfont icon-cangku font-18 mr3"></i>
|
||||
仓库 <span>{projectDetail && projectDetail.size}</span>kb
|
||||
仓库 <span className="ml3">{projectDetail && projectDetail.size}</span>
|
||||
</a>
|
||||
</p>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@
|
|||
padding:12px 10px;
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
background: #EEEEEE;
|
||||
background:rgba(241,248,255,1);
|
||||
}
|
||||
.branchUl{
|
||||
padding:0px 30px;
|
||||
|
|
|
|||
|
|
@ -1,71 +1,145 @@
|
|||
import React , { Component } from "react";
|
||||
import Editor from "react-monaco-editor";
|
||||
import React, { Component } from "react";
|
||||
import Meditor from "./m_editor";
|
||||
import Top from "../Main/DetailTop";
|
||||
import "./index.css";
|
||||
import { Input, Select } from "antd";
|
||||
|
||||
import UserSubmitComponent from './UserSubmitComponent';
|
||||
import Top from '../Main/DetailTop';
|
||||
import { Input } from 'antd';
|
||||
import './index.css';
|
||||
|
||||
class Index extends Component{
|
||||
constructor(props){
|
||||
class Index extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
editorValue:"",
|
||||
filename:""
|
||||
}
|
||||
this.state = {
|
||||
editorValue: "",
|
||||
filename: "",
|
||||
language: undefined
|
||||
};
|
||||
}
|
||||
|
||||
// 命名文件
|
||||
changeFileName=(e)=>{
|
||||
changeFileName = (e) => {
|
||||
this.setState({
|
||||
filename:e.target.value
|
||||
})
|
||||
}
|
||||
filename: e.target.value,
|
||||
});
|
||||
};
|
||||
// 取消,弹框询问
|
||||
CancelAddFile=()=>{
|
||||
CancelAddFile = () => {
|
||||
this.props.history.goBack();
|
||||
}
|
||||
};
|
||||
|
||||
changeEditor=(editorValue)=>{
|
||||
select_language = (e) => {
|
||||
console.log(e)
|
||||
this.setState({
|
||||
editorValue
|
||||
language: e
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
render(){
|
||||
const { editorValue , filename } = this.state;
|
||||
const { projectDetail } = this.props;
|
||||
|
||||
render() {
|
||||
const { pathname } = this.props.location;
|
||||
const { filename, language } = this.state;
|
||||
const urlroot = pathname.split("newfile")[1];
|
||||
return(
|
||||
const file_path = `${urlroot}/${filename}`;
|
||||
const { projectDetail } = this.props;
|
||||
const Option = Select.Option;
|
||||
const languages = [
|
||||
"apex",
|
||||
"azcli",
|
||||
"bat",
|
||||
"clojure",
|
||||
"coffee",
|
||||
"cpp",
|
||||
"csharp",
|
||||
"csp",
|
||||
"css",
|
||||
"dockerfile",
|
||||
"fsharp",
|
||||
"go",
|
||||
"handlebars",
|
||||
"html",
|
||||
"ini",
|
||||
"java",
|
||||
"javascript",
|
||||
"json",
|
||||
"less",
|
||||
"lua",
|
||||
"markdown",
|
||||
"msdax",
|
||||
"mysql",
|
||||
"objective",
|
||||
"perl",
|
||||
"pgsql",
|
||||
"php",
|
||||
"postiats",
|
||||
"powerquery",
|
||||
"powershell",
|
||||
"pug",
|
||||
"python",
|
||||
"r",
|
||||
"razor",
|
||||
"redis",
|
||||
"redshift",
|
||||
"ruby",
|
||||
"rust",
|
||||
"sb",
|
||||
"scheme",
|
||||
"scss",
|
||||
"shell",
|
||||
"solidity",
|
||||
"sql",
|
||||
"st",
|
||||
"swift",
|
||||
"typescript",
|
||||
"vb",
|
||||
"xml",
|
||||
"yaml",
|
||||
];
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Top {...this.props} {...this.state}/>
|
||||
<Top {...this.props} {...this.state} />
|
||||
<div className="main">
|
||||
<p className="pb15 bor-bottom-greyE font-16 color-grey-3 mb20">新建文件</p>
|
||||
<div className="f-wrap-alignCenter mb20">
|
||||
<div className="setInputAddon">
|
||||
<Input addonBefore={`/${projectDetail && projectDetail.identifier}${urlroot}/`} value={filename} onChange={this.changeFileName} placeholder="命名文件..."/>
|
||||
<p className="pb15 bor-bottom-greyE font-16 color-grey-3 mb20">
|
||||
新建文件
|
||||
</p>
|
||||
<div>
|
||||
<div className="grid-item mb20">
|
||||
<div className="grid-item">
|
||||
<div className="setInputAddon">
|
||||
<Input
|
||||
addonBefore={`/${
|
||||
projectDetail && projectDetail.identifier
|
||||
}${urlroot}/`}
|
||||
value={filename}
|
||||
onChange={this.changeFileName}
|
||||
placeholder="命名文件..."
|
||||
/>
|
||||
</div>
|
||||
<a onClick={this.CancelAddFile} className="color-blue">
|
||||
取消
|
||||
</a>
|
||||
</div>
|
||||
<div className="text-right">
|
||||
<Select showSearch={true} placeholder={"请选择文本语言"} style={{ width: 200 }} value={language} onChange={this.select_language}>
|
||||
<Option value={undefined}>请选择文本语言</Option>
|
||||
{languages.map((item, key) => {
|
||||
return <Option value={item}>{item}</Option>;
|
||||
})}
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<a onClick={this.CancelAddFile} className="color-blue">取消</a>
|
||||
<Meditor
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
filepath={`${file_path}`}
|
||||
language = {language}
|
||||
content={undefined}
|
||||
readOnly={false}
|
||||
editorType="new"
|
||||
></Meditor>
|
||||
</div>
|
||||
<div className="branchTable">
|
||||
<Editor
|
||||
height="320px"
|
||||
theme={"vs-grey"}
|
||||
value={editorValue}
|
||||
onChange={this.changeEditor}
|
||||
/>
|
||||
</div>
|
||||
<UserSubmitComponent
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
filepath={`${urlroot}/${filename}`}
|
||||
content={editorValue}
|
||||
></UserSubmitComponent>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
export default Index;
|
||||
export default Index;
|
||||
|
|
|
|||
|
|
@ -1,115 +1,213 @@
|
|||
import React,{Component} from 'react';
|
||||
import { getImageUrl } from 'educoder';
|
||||
import { Form , Input , Button , Radio , Icon } from 'antd';
|
||||
import React, { Component } from "react";
|
||||
import { getImageUrl } from "educoder";
|
||||
import { Form, Input, Button, Radio, Icon } from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import "./index.css";
|
||||
|
||||
import './index.css';
|
||||
|
||||
import axios from 'axios';
|
||||
import axios from "axios";
|
||||
const TextArea = Input.TextArea;
|
||||
class UserSubmitComponent extends Component{
|
||||
constructor(props){
|
||||
class UserSubmitComponent extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
submitType:"0"
|
||||
}
|
||||
this.state = {
|
||||
submitType: "0",
|
||||
};
|
||||
}
|
||||
|
||||
changeSubmittype=(e)=>{
|
||||
changeSubmittype = (e) => {
|
||||
this.setState({
|
||||
submitType:e.target.value
|
||||
})
|
||||
}
|
||||
submitType: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
// 提交变更
|
||||
subMitFrom=()=>{
|
||||
const { filepath , content } = this.props;
|
||||
const { branch , projectsId } = this.props.match.params;
|
||||
subMitFrom = () => {
|
||||
const { filepath, content } = this.props;
|
||||
const { branch, projectsId } = this.props.match.params;
|
||||
const { submitType } = this.state;
|
||||
let path = filepath.substr(1);
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
if (!err) {
|
||||
const url = `/repositories/${projectsId}/create_file.json`;
|
||||
axios.post(url,{
|
||||
filepath:path,
|
||||
branch:branch,
|
||||
new_branch:submitType==="1" ? values.branchname:undefined,
|
||||
content,
|
||||
message:values.desc
|
||||
}).then((result)=>{
|
||||
if(result && result.data.name){
|
||||
const url = values.branchname ? `/projects/${projectsId}/coders?branch=${values.branchname}` : `/projects/${projectsId}/coders`;
|
||||
this.props.history.push(url);
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
axios
|
||||
.post(url, {
|
||||
filepath: path,
|
||||
branch: branch,
|
||||
new_branch: submitType === "1" ? values.branchname : undefined,
|
||||
content,
|
||||
message: values.desc,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result && result.data.name) {
|
||||
const url = values.branchname
|
||||
? `/projects/${projectsId}/coders?branch=${values.branchname}`
|
||||
: `/projects/${projectsId}/coders`;
|
||||
this.props.history.push(url);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
render(){
|
||||
});
|
||||
};
|
||||
|
||||
// 确认修改文件
|
||||
UpdateFile = () => {
|
||||
const { branch, detail, content, filepath } = this.props;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { submitType } = this.state;
|
||||
const url = `/repositories/${projectsId}/update_file.json`;
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if (!err) {
|
||||
axios
|
||||
.put(url, {
|
||||
filepath: detail.path,
|
||||
branch: branch,
|
||||
new_branch: submitType === "1" ? values.branchname : undefined,
|
||||
content: content,
|
||||
sha: detail.sha,
|
||||
message: values.desc,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result && result.data.status === 1) {
|
||||
// const url = `/projects/${projectsId}/coders?url=${detail.path.split("/")[0]}`;
|
||||
// this.props.history.push(url);
|
||||
const url = values.branchname
|
||||
? `/projects/${projectsId}/coders?branch=${values.branchname}`
|
||||
: `/projects/${projectsId}/coders`;
|
||||
this.props.history.push(url);
|
||||
this.props.showNotification("修改成功!");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { submitType } = this.state;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const { branch , projectsId } = this.props.match.params;
|
||||
const { branch, projectsId } = this.props.match.params;
|
||||
|
||||
const { current_user , filepath , projectDetail } = this.props;
|
||||
const { current_user, filepath, projectDetail } = this.props;
|
||||
const { editor_type } = this.props;
|
||||
|
||||
const changeSubmitBranch = ()=>{
|
||||
if(submitType==="1"){
|
||||
return(
|
||||
const changeSubmitBranch = () => {
|
||||
if (submitType === "1") {
|
||||
return (
|
||||
<div className="mt15">
|
||||
<Form.Item style={{paddingLeft:"24px"}}>
|
||||
{getFieldDecorator('branchname', {
|
||||
rules: [{
|
||||
required: true, message: '请输入分支名称'
|
||||
}],
|
||||
<Form.Item style={{ paddingLeft: "24px" }}>
|
||||
{getFieldDecorator("branchname", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入分支名称",
|
||||
},
|
||||
],
|
||||
})(
|
||||
<Input placeholder={`请输入分支名称`} style={{width:"220px"}}/>
|
||||
<Input
|
||||
placeholder={`请输入分支名称`}
|
||||
style={{ width: "220px" }}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return(
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<span className="df mt20" style={{alignItems:"center"}}>
|
||||
<img src={getImageUrl(`images/${current_user && current_user.image_url}`)} alt="" className="screwImg"/>
|
||||
<span className="color-grey-3">用户名:<span className="color-grey-8">{current_user && current_user.username}</span></span>
|
||||
<span className="df mt20" style={{ alignItems: "center" }}>
|
||||
<Link
|
||||
to={`/users/${current_user && current_user.login}/projects`}
|
||||
className="show-user-link"
|
||||
>
|
||||
<img
|
||||
src={getImageUrl(
|
||||
`images/${current_user && current_user.image_url}`
|
||||
)}
|
||||
alt=""
|
||||
className="screwImg"
|
||||
/>
|
||||
<span className="color-grey-3 ver-middle">
|
||||
{current_user && current_user.username}:
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
<span className="color-grey-8">提交变更</span>
|
||||
</span>
|
||||
<div className="userScrew">
|
||||
<div className="screwPanel">
|
||||
<Form>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('path', {
|
||||
<Form.Item style={{display: "none"}}>
|
||||
{getFieldDecorator("path", {
|
||||
rules: [],
|
||||
})(
|
||||
<Input placeholder={`/${projectDetail && projectDetail.identifier}${filepath}`} readOnly/>
|
||||
<Input
|
||||
placeholder={`/${
|
||||
projectDetail && projectDetail.identifier
|
||||
}${filepath}`}
|
||||
readOnly
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
{getFieldDecorator('desc', {
|
||||
rules: [{
|
||||
required:true,message:'请输入合并请求的描述内容'
|
||||
}],
|
||||
{getFieldDecorator("desc", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请添加描述信息",
|
||||
},
|
||||
],
|
||||
})(
|
||||
<TextArea placeholder={`请输入合并请求的描述,(必填)`} authSize={{minRows:3,maxRows:5}}/>
|
||||
<TextArea
|
||||
placeholder={`必填,描述主要修改类型和内容`}
|
||||
authSize={{ minRows: 3, maxRows: 5 }}
|
||||
/>
|
||||
)}
|
||||
</Form.Item>
|
||||
<Radio.Group value={submitType} onChange={this.changeSubmittype}>
|
||||
<Radio value="0" className="mb10"><i className="iconfont icon-banbenku font-16 mr5"></i>直接提交至<span className="color-orange">{branch}</span>分支</Radio>
|
||||
<Radio value="1"><Icon type="pull-request" className="mr5" />为此提交创建一个<span className="font-bd">新的分支</span>并发起合并请求</Radio>
|
||||
<Radio value="0" className="mb10">
|
||||
<i className="iconfont icon-banbenku font-16 mr5"></i>
|
||||
直接提交至<span className="color-orange">{branch}</span>分支
|
||||
</Radio>
|
||||
<Radio value="1">
|
||||
<Icon type="pull-request" className="mr5" />
|
||||
为此提交创建一个<span className="font-bd">新的分支</span>
|
||||
并发起合并请求
|
||||
</Radio>
|
||||
</Radio.Group>
|
||||
{changeSubmitBranch()}
|
||||
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
<Button type="primary" onClick={this.subMitFrom} className="mr20">提交变更</Button>
|
||||
<Button type="primary grey" onClick={()=>{this.props.history.push(`/projects/${projectsId}/coders`)}} className="mr20">取消</Button>
|
||||
<div className="mt50 text-center">
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={editor_type === "new" ? this.subMitFrom : this.UpdateFile}
|
||||
className="mr30"
|
||||
>
|
||||
提交变更
|
||||
</Button>
|
||||
<Button
|
||||
type="primary grey"
|
||||
onClick={() => {
|
||||
this.props.history.push(`/projects/${projectsId}/coders`);
|
||||
}}
|
||||
className="mr20"
|
||||
>
|
||||
取消
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
const WrappedUserSubmitForm = Form.create({ name: 'UserSubmitForm' })(UserSubmitComponent);
|
||||
export default WrappedUserSubmitForm;
|
||||
const WrappedUserSubmitForm = Form.create({ name: "UserSubmitForm" })(
|
||||
UserSubmitComponent
|
||||
);
|
||||
export default WrappedUserSubmitForm;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
.monaco-editor .view-overlays .current-line{
|
||||
border: none !important;
|
||||
background-color: rgba(48,232,132,0.15);
|
||||
}
|
||||
.monaco-editor .margin-view-overlays .current-line{
|
||||
background-color: rgba(48,232,132,0.15);
|
||||
}
|
||||
.branchTable .margin-view-overlays{border-right: none !important; background-color: #fcfcfc !important;}
|
||||
|
|
@ -75,4 +75,6 @@
|
|||
width: 100%;
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.grid-item{display: grid; align-items: center; grid-template-columns: max-content 1fr;}
|
||||
.text-right{text-align: right;}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import React, { Component } from "react";
|
||||
import Editor from "react-monaco-editor";
|
||||
|
||||
import UserSubmitComponent from "./UserSubmitComponent";
|
||||
|
||||
import "./index.css";
|
||||
import "./editor.css";
|
||||
|
||||
class m_editor extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
editorValue: this.props.content,
|
||||
};
|
||||
}
|
||||
changeEditor = (editorValue) => {
|
||||
this.setState({
|
||||
editorValue,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { editorValue } = this.state;
|
||||
const { readOnly, editorType, language } = this.props;
|
||||
const editor_options = {
|
||||
lineNumbers: "on",
|
||||
selectOnLineNumbers: true,
|
||||
lineHeight: 24,
|
||||
renderLineHighlight: "line",
|
||||
revealHorizontalRightPadding: 5,
|
||||
readOnly: readOnly,
|
||||
cursorStyle: readOnly ? "underline-thin" : "line",
|
||||
folding: true,
|
||||
foldingStrategy: "indentation", // 代码可分小段折叠
|
||||
automaticLayout: true, // 自适应布局
|
||||
overviewRulerBorder: false, // 不要滚动条的边框
|
||||
scrollBeyondLastLine: false, // 取消代码后面一大段空白
|
||||
minimap: {
|
||||
// 不要小地图
|
||||
enabled: false,
|
||||
},
|
||||
};
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<div className="branchTable">
|
||||
<Editor
|
||||
height="320px"
|
||||
language={language ? language : "plaintext"}
|
||||
theme={"vs-grey"}
|
||||
defaultValue="请输入内容"
|
||||
value={editorValue}
|
||||
options={editor_options}
|
||||
onChange={this.changeEditor}
|
||||
editorWillMount={this.editorWillMount}
|
||||
/>
|
||||
</div>
|
||||
{!readOnly && (
|
||||
<UserSubmitComponent
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
filepath={`${this.props.filepath}`}
|
||||
content={editorValue}
|
||||
editor_type={editorType}
|
||||
></UserSubmitComponent>
|
||||
)}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
export default m_editor;
|
||||
|
|
@ -85,7 +85,8 @@ class Detail extends Component {
|
|||
})
|
||||
if (!quillValue) {
|
||||
this.setState({
|
||||
quillFlag: true
|
||||
quillFlag: true,
|
||||
journal_spin: false
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,8 +399,8 @@
|
|||
/*}*/
|
||||
.tagColor{
|
||||
display: inline-block;
|
||||
width:20px;
|
||||
height: 15px;
|
||||
width:28px;
|
||||
height: 14px;
|
||||
border-radius: 4px;
|
||||
margin-right: 5px;
|
||||
vertical-align: middle;
|
||||
|
|
|
|||
|
|
@ -175,6 +175,10 @@ class Collaborator extends Component {
|
|||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
otherSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
|
@ -201,6 +205,9 @@ class Collaborator extends Component {
|
|||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
|
@ -229,6 +236,9 @@ class Collaborator extends Component {
|
|||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
this.setState({
|
||||
isSpin: false,
|
||||
});
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,300 +1,405 @@
|
|||
import React , {Component} from 'react';
|
||||
import { Dropdown , Icon , Menu , Pagination, Modal,Input,Popconfirm,Form, Spin, Button } from 'antd';
|
||||
import { Link } from 'react-router-dom';
|
||||
import '../Order/order.css'
|
||||
import React, { Component } from "react";
|
||||
import {
|
||||
Dropdown,
|
||||
Icon,
|
||||
Menu,
|
||||
Pagination,
|
||||
Modal,
|
||||
Input,
|
||||
Popconfirm,
|
||||
Form,
|
||||
Spin,
|
||||
Button,
|
||||
Table,
|
||||
} from "antd";
|
||||
import { Link } from "react-router-dom";
|
||||
import "../Order/order.css";
|
||||
import "./setting.css";
|
||||
import NoneData from '../Nodata';
|
||||
import { SketchPicker } from 'react-color'
|
||||
import reactCSS from 'reactcss'
|
||||
import axios from 'axios';
|
||||
class NewTags extends Component{
|
||||
constructor(props){
|
||||
import NoneData from "../Nodata";
|
||||
import { SketchPicker } from "react-color";
|
||||
import reactCSS from "reactcss";
|
||||
import axios from "axios";
|
||||
class NewTags extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state={
|
||||
data:undefined,
|
||||
limit:15,
|
||||
page:1,
|
||||
order_name:undefined,
|
||||
order_type:undefined,
|
||||
this.state = {
|
||||
data: undefined,
|
||||
limit: 15,
|
||||
page: 1,
|
||||
order_name: undefined,
|
||||
order_type: undefined,
|
||||
//新建标签区域是否显示 none 隐藏 block 显示
|
||||
display:'none',
|
||||
display: "none",
|
||||
//调色盘颜色
|
||||
displayColorPicker: false,
|
||||
color: {
|
||||
r: '241',
|
||||
g: '112',
|
||||
b: '19',
|
||||
a: '1',
|
||||
r: "241",
|
||||
g: "112",
|
||||
b: "19",
|
||||
a: "1",
|
||||
},
|
||||
textcolor:'#F17013',
|
||||
isShow:false,
|
||||
newcolor:'',
|
||||
name:'',
|
||||
description:'',
|
||||
id:'',
|
||||
modelname:'',
|
||||
isSpin: false
|
||||
}
|
||||
textcolor: "#F17013",
|
||||
isShow: false,
|
||||
newcolor: "",
|
||||
name: "",
|
||||
description: "",
|
||||
id: "",
|
||||
modelname: "",
|
||||
isSpin: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount=()=>{
|
||||
componentDidMount = () => {
|
||||
this.getList();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
getList=(page,order_name,order_type)=>{
|
||||
getList = (page, order_name, order_type) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { limit } = this.state;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
axios.get(url,{
|
||||
params:{
|
||||
page,limit,order_name,order_type
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
data:result.data
|
||||
})
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
axios
|
||||
.get(url, {
|
||||
params: {
|
||||
page,
|
||||
limit,
|
||||
order_name,
|
||||
order_type,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
data: result.data,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
createtagpost=()=>{
|
||||
createtagpost = () => {
|
||||
this.props.form.validateFieldsAndScroll((err, values) => {
|
||||
if(!err){
|
||||
if (!err) {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags.json`;
|
||||
axios.post(url,{
|
||||
...values,
|
||||
project_id:projectsId,
|
||||
color:this.state.textcolor
|
||||
}).then(result=>{
|
||||
if(result){
|
||||
this.props.form.setFieldsValue({
|
||||
name: "",
|
||||
description: ""
|
||||
});
|
||||
this.setState({
|
||||
color: {
|
||||
r: '241',
|
||||
g: '112',
|
||||
b: '19',
|
||||
a: '1',
|
||||
},
|
||||
textcolor:'#F17013',
|
||||
display:'none'
|
||||
});
|
||||
this.getList()
|
||||
}
|
||||
}).catch(error=>{
|
||||
console.log(error);
|
||||
})
|
||||
axios
|
||||
.post(url, {
|
||||
...values,
|
||||
project_id: projectsId,
|
||||
color: this.state.textcolor,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.props.form.setFieldsValue({
|
||||
name: "",
|
||||
description: "",
|
||||
});
|
||||
this.setState({
|
||||
color: {
|
||||
r: "241",
|
||||
g: "112",
|
||||
b: "19",
|
||||
a: "1",
|
||||
},
|
||||
textcolor: "#F17013",
|
||||
display: "none",
|
||||
});
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ChangePage=(page)=>{
|
||||
ChangePage = (page) => {
|
||||
this.setState({
|
||||
page
|
||||
})
|
||||
page,
|
||||
});
|
||||
|
||||
this.getList(page);
|
||||
}
|
||||
};
|
||||
|
||||
// 排序
|
||||
arrayList=(e)=>{
|
||||
arrayList = (e) => {
|
||||
this.setState({
|
||||
order_name:e.key,
|
||||
order_type:e.item.props.value
|
||||
})
|
||||
order_name: e.key,
|
||||
order_type: e.item.props.value,
|
||||
});
|
||||
|
||||
this.getList(1,e.key,e.item.props.value);
|
||||
}
|
||||
this.getList(1, e.key, e.item.props.value);
|
||||
};
|
||||
|
||||
handleClick = () => {
|
||||
this.setState({ displayColorPicker: !this.state.displayColorPicker })
|
||||
this.setState({ displayColorPicker: !this.state.displayColorPicker });
|
||||
};
|
||||
|
||||
handleClose = () => {
|
||||
this.setState({ displayColorPicker: false })
|
||||
this.setState({ displayColorPicker: false });
|
||||
};
|
||||
|
||||
handleChange = (color) => {
|
||||
this.setState({
|
||||
color: color.rgb,
|
||||
textcolor:color.hex,
|
||||
newcolor:color.hex,
|
||||
})
|
||||
textcolor: color.hex,
|
||||
newcolor: color.hex,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
//控制新建标签页是否显示
|
||||
newshow=()=>{
|
||||
newshow = () => {
|
||||
this.setState({
|
||||
display:'block'
|
||||
display: "block",
|
||||
});
|
||||
|
||||
};
|
||||
newclose=()=>{
|
||||
newclose = () => {
|
||||
this.setState({
|
||||
display:'none'
|
||||
display: "none",
|
||||
});
|
||||
};
|
||||
|
||||
handleok=()=>{
|
||||
handleok = () => {
|
||||
this.updatetag();
|
||||
}
|
||||
updatetag=()=>{
|
||||
};
|
||||
updatetag = () => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
let id=this.state.id;
|
||||
let id = this.state.id;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
let name=this.state.name;
|
||||
let description=this.state.description;
|
||||
let modalcolor=this.state.newcolor
|
||||
axios.put(url,{
|
||||
project_id:projectsId,
|
||||
id:id,
|
||||
name:name,
|
||||
description:description,
|
||||
color:modalcolor
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.setState({
|
||||
isShow:false
|
||||
});
|
||||
this.getList()
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
deletetag=(id)=>{
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
axios.delete(url,{ data: {
|
||||
let name = this.state.name;
|
||||
let description = this.state.description;
|
||||
let modalcolor = this.state.newcolor;
|
||||
axios
|
||||
.put(url, {
|
||||
project_id: projectsId,
|
||||
id: id
|
||||
}
|
||||
}).then((result)=>{
|
||||
if(result){
|
||||
this.getList()
|
||||
}
|
||||
}).catch((error)=>{
|
||||
console.log(error);
|
||||
})
|
||||
}
|
||||
id: id,
|
||||
name: name,
|
||||
description: description,
|
||||
color: modalcolor,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.setState({
|
||||
isShow: false,
|
||||
});
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel=()=>{
|
||||
this.setState({
|
||||
isShow:false
|
||||
});
|
||||
}
|
||||
deletetag = (id) => {
|
||||
const { projectsId } = this.props.match.params;
|
||||
const url = `/projects/${projectsId}/issue_tags/${id}.json`;
|
||||
axios
|
||||
.delete(url, {
|
||||
data: {
|
||||
project_id: projectsId,
|
||||
id: id,
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
if (result) {
|
||||
this.getList();
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
};
|
||||
|
||||
changmodelname=(e)=>{
|
||||
handleCancel = () => {
|
||||
this.setState({
|
||||
name:e.target.value
|
||||
})
|
||||
}
|
||||
changdescription=(e)=>{
|
||||
this.setState({
|
||||
description:e.target.value
|
||||
})
|
||||
}
|
||||
|
||||
editshow=(arr)=>{
|
||||
this.setState({
|
||||
isShow:true,
|
||||
newcolor:arr.color,
|
||||
name:arr.name,
|
||||
description:arr.description,
|
||||
id:arr.id
|
||||
isShow: false,
|
||||
});
|
||||
};
|
||||
|
||||
render(){
|
||||
const { data , limit , page, isSpin } = this.state;
|
||||
changmodelname = (e) => {
|
||||
this.setState({
|
||||
name: e.target.value,
|
||||
});
|
||||
};
|
||||
changdescription = (e) => {
|
||||
this.setState({
|
||||
description: e.target.value,
|
||||
});
|
||||
};
|
||||
|
||||
editshow = (arr) => {
|
||||
this.setState({
|
||||
isShow: true,
|
||||
newcolor: arr.color,
|
||||
name: arr.name,
|
||||
description: arr.description,
|
||||
id: arr.id,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { data, limit, page, isSpin } = this.state;
|
||||
const { projectsId } = this.props.match.params;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
|
||||
const menu = (
|
||||
<Menu onClick={this.arrayList}>
|
||||
<Menu.Item key={'created_at'} value="desc">按创建时间降序排序</Menu.Item>
|
||||
<Menu.Item key={'created_at'} value="asc">按创建时间升序排序</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="desc">按issue个数降序排序</Menu.Item>
|
||||
<Menu.Item key={'issues_count'} value="asc">按issue个数升序排序</Menu.Item>
|
||||
<Menu.Item key={"created_at"} value="desc">
|
||||
按创建时间降序排序
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"created_at"} value="asc">
|
||||
按创建时间升序排序
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"issues_count"} value="desc">
|
||||
按issue个数降序排序
|
||||
</Menu.Item>
|
||||
<Menu.Item key={"issues_count"} value="asc">
|
||||
按issue个数升序排序
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
)
|
||||
);
|
||||
const styles = reactCSS({
|
||||
'default': {
|
||||
default: {
|
||||
color: {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
borderRadius: '2px',
|
||||
background: `rgba(${ this.state.color.r }, ${ this.state.color.g }, ${ this.state.color.b }, ${ this.state.color.a })`,
|
||||
width: "20px",
|
||||
height: "20px",
|
||||
borderRadius: "2px",
|
||||
background: `rgba(${this.state.color.r}, ${this.state.color.g}, ${this.state.color.b}, ${this.state.color.a})`,
|
||||
},
|
||||
swatch: {
|
||||
padding: '5px',
|
||||
background: '#fff',
|
||||
borderRadius: '1px',
|
||||
width:'100px',
|
||||
marginTop:'5px',
|
||||
height:'28px',
|
||||
boxShadow: '0 0 0 1px rgba(0,0,0,.1)',
|
||||
display: 'flex',
|
||||
cursor: 'pointer',
|
||||
padding: "5px",
|
||||
background: "#fff",
|
||||
borderRadius: "1px",
|
||||
width: "100px",
|
||||
marginTop: "5px",
|
||||
height: "28px",
|
||||
boxShadow: "0 0 0 1px rgba(0,0,0,.1)",
|
||||
display: "flex",
|
||||
cursor: "pointer",
|
||||
},
|
||||
popover: {
|
||||
position: 'absolute',
|
||||
zIndex: '2',
|
||||
position: "absolute",
|
||||
zIndex: "2",
|
||||
},
|
||||
cover: {
|
||||
position: 'fixed',
|
||||
top: '0px',
|
||||
right: '0px',
|
||||
bottom: '0px',
|
||||
left: '0px',
|
||||
position: "fixed",
|
||||
top: "0px",
|
||||
right: "0px",
|
||||
bottom: "0px",
|
||||
left: "0px",
|
||||
},
|
||||
modalcolor:{
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
borderRadius: '2px',
|
||||
modalcolor: {
|
||||
width: "20px",
|
||||
height: "20px",
|
||||
borderRadius: "2px",
|
||||
background: this.state.newcolor,
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: "颜色代码",
|
||||
width: "20%",
|
||||
dataIndex: "color",
|
||||
render: (text, item) => (
|
||||
<span className="grid-item">
|
||||
<span
|
||||
style={{ backgroundColor: `${item.color}` }}
|
||||
className="tagColor"
|
||||
></span>
|
||||
<span className="ml15">{item.name}</span>
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "描述",
|
||||
width: "30%",
|
||||
dataIndex: "description",
|
||||
render: (text) => <span>{text}</span>,
|
||||
},
|
||||
{
|
||||
title: "问题数量",
|
||||
width: "30%",
|
||||
dataIndex: "issues_count",
|
||||
render: (text) => <span>{text}个开启的任务</span>,
|
||||
},
|
||||
{
|
||||
title: "操作",
|
||||
width: "20%",
|
||||
dataIndex: "action",
|
||||
render: (text, item) => (
|
||||
<span style={{ justifyContent: "center" }}>
|
||||
<a
|
||||
onClick={() => this.editshow(item)}
|
||||
className="topWrapper_success_btn fr"
|
||||
>
|
||||
编辑
|
||||
</a>
|
||||
<Popconfirm
|
||||
placement="bottom"
|
||||
title={"删除标签会将其从所有引用中删除。继续?"}
|
||||
okText="是"
|
||||
cancelText="否"
|
||||
onConfirm={() => this.deletetag(item.id)}
|
||||
>
|
||||
<a className="a_btn delete_btn fr">删除</a>
|
||||
</Popconfirm>
|
||||
</span>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
const Paginations = (
|
||||
<React.Fragment>
|
||||
{
|
||||
data && data.issue_tags_count > limit ?
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination simple defaultCurrent={page} total={data && data.issue_tags_count} pageSize={limit} onChange={this.ChangePage}></Pagination>
|
||||
</div>:""
|
||||
}
|
||||
{data && data.issue_tags_count > limit ? (
|
||||
<div className="mt30 mb50 edu-txt-center">
|
||||
<Pagination
|
||||
simple
|
||||
defaultCurrent={page}
|
||||
total={data && data.issue_tags_count}
|
||||
pageSize={limit}
|
||||
onChange={this.ChangePage}
|
||||
></Pagination>
|
||||
</div>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</React.Fragment>
|
||||
)
|
||||
);
|
||||
|
||||
const renderList =()=>{
|
||||
if(data && data.issue_tags && data.issue_tags.length>0 ){
|
||||
return(
|
||||
const renderList = () => {
|
||||
if (data && data.issue_tags && data.issue_tags.length > 0) {
|
||||
return (
|
||||
<div>
|
||||
<div className="topWrapper">
|
||||
<span>共{ data && data.issue_tags_count }个标签</span>
|
||||
<span>共{data && data.issue_tags_count}个标签</span>
|
||||
<ul className="topWrapper_select">
|
||||
<li>
|
||||
<Dropdown className="topWrapperSelect" overlay={menu} trigger={['click']} placement="bottomCenter">
|
||||
<span>标签<Icon type="caret-down" className="ml5" /></span>
|
||||
<Dropdown
|
||||
className="topWrapperSelect"
|
||||
overlay={menu}
|
||||
trigger={["click"]}
|
||||
placement="bottomCenter"
|
||||
>
|
||||
<span>
|
||||
标签
|
||||
<Icon type="caret-down" className="ml5" />
|
||||
</span>
|
||||
</Dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="tagList">
|
||||
{
|
||||
<div>
|
||||
<Table
|
||||
showHeader={false}
|
||||
pagination={false}
|
||||
columns={columns}
|
||||
dataSource={data.issue_tags}
|
||||
rowKey={(record) => record.id}
|
||||
></Table>
|
||||
{/* {
|
||||
data.issue_tags.map((item,key)=>{
|
||||
return(
|
||||
<div>
|
||||
|
|
@ -318,95 +423,95 @@ class NewTags extends Component{
|
|||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
} */}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}else{
|
||||
return(
|
||||
<NoneData _html="暂时还没有相关数据哦!" />
|
||||
)
|
||||
);
|
||||
} else {
|
||||
return <NoneData _html="暂时还没有相关数据哦!" />;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return(
|
||||
return (
|
||||
<div className="">
|
||||
<div className="flex-a-center baseForm bbr" style={{"justify-content":"space-between"}}>
|
||||
<span className="font-18 fwb text-black">项目标签</span>
|
||||
{
|
||||
data && data.user_admin_or_member ?
|
||||
<Button type="primary" onClick={this.newshow}>
|
||||
<Icon type="plus"></Icon>
|
||||
创建标签
|
||||
</Button>
|
||||
|
||||
: ''
|
||||
}
|
||||
</div>
|
||||
<div
|
||||
className="flex-a-center baseForm bbr"
|
||||
style={{ "justify-content": "space-between" }}
|
||||
>
|
||||
<span className="font-18 fwb text-black">项目标签</span>
|
||||
{data && data.user_admin_or_member ? (
|
||||
<Button type="primary" onClick={this.newshow}>
|
||||
<Icon type="plus"></Icon>
|
||||
创建标签
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{display: this.state.display}} className="padding15">
|
||||
<div style={{ display: this.state.display }} className="padding15">
|
||||
<Form>
|
||||
<div className="new-tag-div" >
|
||||
<Form.Item
|
||||
className="inptwidth"
|
||||
>
|
||||
{getFieldDecorator('name', {
|
||||
rules: [{
|
||||
required: true, message: '请填写标签名字'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="标签名字" maxLength="10"/>
|
||||
|
||||
)}
|
||||
<div className="new-tag-div">
|
||||
<Form.Item className="inptwidth">
|
||||
{getFieldDecorator("name", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "请填写标签名字",
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="标签名字" maxLength="10" />)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
className="inputcount"
|
||||
>
|
||||
{getFieldDecorator('description', {
|
||||
rules: [{
|
||||
required: true, message: '描述不能为空'
|
||||
}],
|
||||
})(
|
||||
<Input placeholder="描述, 30字以内" maxLength="30"/>
|
||||
)}
|
||||
<Form.Item className="inputcount">
|
||||
{getFieldDecorator("description", {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: "描述不能为空",
|
||||
},
|
||||
],
|
||||
})(<Input placeholder="描述, 30字以内" maxLength="30" />)}
|
||||
</Form.Item>
|
||||
|
||||
|
||||
<div>
|
||||
<div style={ styles.swatch } onClick={ this.handleClick }>
|
||||
<div style={ styles.color }>
|
||||
<p style={{paddingLeft:25}}>{this.state.textcolor}</p>
|
||||
<div style={styles.swatch} onClick={this.handleClick}>
|
||||
<div style={styles.color}>
|
||||
<p style={{ paddingLeft: 25 }}>{this.state.textcolor}</p>
|
||||
</div>
|
||||
</div>
|
||||
{ this.state.displayColorPicker ? <div style={ styles.popover }>
|
||||
<div style={ styles.cover } onClick={ this.handleClose }/>
|
||||
<SketchPicker color={ this.state.color } onChange={ this.handleChange } />
|
||||
</div> :
|
||||
null }
|
||||
{this.state.displayColorPicker ? (
|
||||
<div style={styles.popover}>
|
||||
<div style={styles.cover} onClick={this.handleClose} />
|
||||
<SketchPicker
|
||||
color={this.state.color}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="fr" style={{marginTop:5}}>
|
||||
<Spin spinning={isSpin}>
|
||||
<Button type="primary" onClick={this.createtagpost} className="fr">
|
||||
创建标签
|
||||
</Button>
|
||||
{/* <a onClick={this.createtagpost} className="topWrapper_btn fr" >创建标签</a> */}
|
||||
<a onClick={this.newclose} className="a_btn cancel_btn fr" >取消</a>
|
||||
</Spin>
|
||||
|
||||
<div className="fr" style={{ marginTop: 5 }}>
|
||||
<Spin spinning={isSpin}>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={this.createtagpost}
|
||||
className="fr"
|
||||
>
|
||||
创建标签
|
||||
</Button>
|
||||
{/* <a onClick={this.createtagpost} className="topWrapper_btn fr" >创建标签</a> */}
|
||||
<a onClick={this.newclose} className="a_btn cancel_btn fr">
|
||||
取消
|
||||
</a>
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
</Form>
|
||||
|
||||
|
||||
</div>
|
||||
<div className="padding15">
|
||||
{ renderList() }
|
||||
{ Paginations }
|
||||
{renderList()}
|
||||
{Paginations}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<Modal
|
||||
title="编辑标签"
|
||||
|
|
@ -417,27 +522,43 @@ class NewTags extends Component{
|
|||
width="60%"
|
||||
>
|
||||
<div className="dialogdiv">
|
||||
<Input placeholder="标签名字" maxLength="10" className="inptwidth" value={this.state.name} onChange={this.changmodelname}/>
|
||||
<Input placeholder="描述, 30字以内" maxLength="30" className="inputcount" value={this.state.description} onChange={this.changdescription}/>
|
||||
<Input
|
||||
placeholder="标签名字"
|
||||
maxLength="10"
|
||||
className="inptwidth"
|
||||
value={this.state.name}
|
||||
onChange={this.changmodelname}
|
||||
/>
|
||||
<Input
|
||||
placeholder="描述, 30字以内"
|
||||
maxLength="30"
|
||||
className="inputcount"
|
||||
value={this.state.description}
|
||||
onChange={this.changdescription}
|
||||
/>
|
||||
<div>
|
||||
<div style={ styles.swatch } onClick={ this.handleClick }>
|
||||
<div style={ styles.modalcolor }>
|
||||
<p style={{paddingLeft:25,width:100}}>{this.state.newcolor}</p>
|
||||
<div style={styles.swatch} onClick={this.handleClick}>
|
||||
<div style={styles.modalcolor}>
|
||||
<p style={{ paddingLeft: 25, width: 100 }}>
|
||||
{this.state.newcolor}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{ this.state.displayColorPicker ? <div style={ styles.popover }>
|
||||
<div style={ styles.cover } onClick={ this.handleClose }/>
|
||||
<SketchPicker color={ this.state.color } onChange={ this.handleChange } />
|
||||
</div> :
|
||||
null }
|
||||
{this.state.displayColorPicker ? (
|
||||
<div style={styles.popover}>
|
||||
<div style={styles.cover} onClick={this.handleClose} />
|
||||
<SketchPicker
|
||||
color={this.state.color}
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
const WrappedTags = Form.create({ name: 'tageFrom' })(NewTags);
|
||||
export default WrappedTags;
|
||||
const WrappedTags = Form.create({ name: "tageFrom" })(NewTags);
|
||||
export default WrappedTags;
|
||||
|
|
|
|||
|
|
@ -123,4 +123,13 @@
|
|||
background: #fafafa;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.topWrapper_success_btn{
|
||||
border: 1px solid #21ba45;
|
||||
color: #21ba45!important;
|
||||
padding: 0px 12px;
|
||||
text-align: center;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -113,3 +113,6 @@ ul,ol,dl{
|
|||
width: 100%;
|
||||
}
|
||||
}
|
||||
.ver-middle{
|
||||
vertical-align: middle;
|
||||
}
|
||||
Loading…
Reference in New Issue