Commit 4f79c3bb authored by nano's avatar nano

update

parent 3d31834a
......@@ -2,11 +2,15 @@
"parser": "babel-eslint",
"extends": "airbnb",
"rules": {
"react/jsx-space-before-closing":[0],
"generator-star-spacing": [0],
"semi":[0],
"no-console":[0],
"consistent-return": [0],
"react/forbid-prop-types": [0],
"react/jsx-filename-extension": [1, { "extensions": [".js"] }],
"global-require": [1],
"react/jsx-closing-bracket-location":[0],
"import/prefer-default-export": [0],
"react/jsx-no-bind": [0],
"react/prop-types": [0],
......@@ -22,11 +26,16 @@
"no-bitwise": [0],
"no-cond-assign": [0],
"import/no-unresolved": [0],
"require-yield": [1]
"require-yield": [1],
"react/react-in-jsx-scope": [0],
"no-extra-semi": [0]
},
"parserOptions": {
"ecmaFeatures": {
"experimentalObjectRestSpread": true
}
},
"env": {
"browser": true
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DBNavigator.Project.DataEditorManager">
<record-view-column-sorting-type value="BY_INDEX" />
<value-preview-text-wrapping value="true" />
<value-preview-pinned value="false" />
</component>
<component name="DBNavigator.Project.DataExportManager">
<export-instructions>
<create-header value="true" />
<quote-values-containing-separator value="true" />
<quote-all-values value="false" />
<value-separator value="" />
<file-name value="" />
<file-location value="" />
<scope value="GLOBAL" />
<destination value="FILE" />
<format value="EXCEL" />
<charset value="UTF-8" />
</export-instructions>
</component>
<component name="DBNavigator.Project.DatabaseBrowserManager">
<autoscroll-to-editor value="false" />
<autoscroll-from-editor value="true" />
<show-object-properties value="true" />
<loaded-nodes />
</component>
<component name="DBNavigator.Project.EditorStateManager">
<last-used-providers />
</component>
<component name="DBNavigator.Project.MethodExecutionManager">
<method-browser />
<execution-history>
<group-entries value="true" />
<execution-inputs />
</execution-history>
<argument-values-cache />
</component>
<component name="DBNavigator.Project.ObjectDependencyManager">
<last-used-dependency-type value="INCOMING" />
</component>
<component name="DBNavigator.Project.ObjectQuickFilterManager">
<last-used-operator value="EQUAL" />
<filters />
</component>
<component name="DBNavigator.Project.ScriptExecutionManager" clear-outputs="true">
<recently-used-interfaces />
</component>
<component name="DBNavigator.Project.Settings">
<connections />
<browser-settings>
<general>
<display-mode value="TABBED" />
<navigation-history-size value="100" />
<show-object-details value="false" />
</general>
<filters>
<object-type-filter>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="true" />
<object-type name="ROLE" enabled="true" />
<object-type name="PRIVILEGE" enabled="true" />
<object-type name="CHARSET" enabled="true" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED_VIEW" enabled="true" />
<object-type name="NESTED_TABLE" enabled="true" />
<object-type name="COLUMN" enabled="true" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET_TRIGGER" enabled="true" />
<object-type name="DATABASE_TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="true" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE_ATTRIBUTE" enabled="true" />
<object-type name="ARGUMENT" enabled="true" />
<object-type name="DIMENSION" enabled="true" />
<object-type name="CLUSTER" enabled="true" />
<object-type name="DBLINK" enabled="true" />
</object-type-filter>
</filters>
<sorting>
<object-type name="COLUMN" sorting-type="NAME" />
<object-type name="FUNCTION" sorting-type="NAME" />
<object-type name="PROCEDURE" sorting-type="NAME" />
<object-type name="ARGUMENT" sorting-type="POSITION" />
</sorting>
<default-editors>
<object-type name="VIEW" editor-type="SELECTION" />
<object-type name="PACKAGE" editor-type="SELECTION" />
<object-type name="TYPE" editor-type="SELECTION" />
</default-editors>
</browser-settings>
<navigation-settings>
<lookup-filters>
<lookup-objects>
<object-type name="SCHEMA" enabled="true" />
<object-type name="USER" enabled="false" />
<object-type name="ROLE" enabled="false" />
<object-type name="PRIVILEGE" enabled="false" />
<object-type name="CHARSET" enabled="false" />
<object-type name="TABLE" enabled="true" />
<object-type name="VIEW" enabled="true" />
<object-type name="MATERIALIZED VIEW" enabled="true" />
<object-type name="NESTED TABLE" enabled="false" />
<object-type name="COLUMN" enabled="false" />
<object-type name="INDEX" enabled="true" />
<object-type name="CONSTRAINT" enabled="true" />
<object-type name="DATASET TRIGGER" enabled="true" />
<object-type name="DATABASE TRIGGER" enabled="true" />
<object-type name="SYNONYM" enabled="false" />
<object-type name="SEQUENCE" enabled="true" />
<object-type name="PROCEDURE" enabled="true" />
<object-type name="FUNCTION" enabled="true" />
<object-type name="PACKAGE" enabled="true" />
<object-type name="TYPE" enabled="true" />
<object-type name="TYPE ATTRIBUTE" enabled="false" />
<object-type name="ARGUMENT" enabled="false" />
<object-type name="DIMENSION" enabled="false" />
<object-type name="CLUSTER" enabled="false" />
<object-type name="DBLINK" enabled="true" />
</lookup-objects>
<force-database-load value="false" />
<prompt-connection-selection value="true" />
<prompt-schema-selection value="true" />
</lookup-filters>
</navigation-settings>
<dataset-grid-settings>
<general>
<enable-zooming value="true" />
</general>
<sorting>
<nulls-first value="true" />
<max-sorting-columns value="4" />
</sorting>
<tracking-columns>
<columnNames value="" />
<visible value="true" />
<editable value="false" />
</tracking-columns>
</dataset-grid-settings>
<dataset-editor-settings>
<text-editor-popup>
<active value="false" />
<active-if-empty value="false" />
<data-length-threshold value="100" />
<popup-delay value="1000" />
</text-editor-popup>
<values-list-popup>
<show-popup-button value="true" />
<element-count-threshold value="1000" />
<data-length-threshold value="250" />
</values-list-popup>
<general>
<fetch-block-size value="100" />
<fetch-timeout value="30" />
<trim-whitespaces value="true" />
<convert-empty-strings-to-null value="true" />
<select-content-on-cell-edit value="true" />
<large-value-preview-active value="true" />
</general>
<filters>
<prompt-filter-dialog value="true" />
<default-filter-type value="BASIC" />
</filters>
<qualified-text-editor text-length-threshold="300">
<content-types>
<content-type name="Text" enabled="true" />
<content-type name="XML" enabled="true" />
<content-type name="DTD" enabled="true" />
<content-type name="HTML" enabled="true" />
<content-type name="XHTML" enabled="true" />
<content-type name="CSS" enabled="true" />
<content-type name="SQL" enabled="true" />
<content-type name="PL/SQL" enabled="true" />
<content-type name="JavaScript" enabled="true" />
<content-type name="JSP" enabled="true" />
<content-type name="JSPx" enabled="true" />
<content-type name="ASP" enabled="true" />
<content-type name="YAML" enabled="true" />
</content-types>
</qualified-text-editor>
<record-navigation>
<navigation-target value="VIEWER" />
</record-navigation>
</dataset-editor-settings>
<code-editor-settings>
<general>
<show-object-navigation-gutter value="false" />
<show-spec-declaration-navigation-gutter value="true" />
</general>
<confirmations>
<save-changes value="false" />
<revert-changes value="true" />
</confirmations>
</code-editor-settings>
<code-completion-settings>
<filters>
<basic-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="false" />
<filter-element type="OBJECT" id="view" selected="false" />
<filter-element type="OBJECT" id="materialized view" selected="false" />
<filter-element type="OBJECT" id="index" selected="false" />
<filter-element type="OBJECT" id="constraint" selected="false" />
<filter-element type="OBJECT" id="trigger" selected="false" />
<filter-element type="OBJECT" id="synonym" selected="false" />
<filter-element type="OBJECT" id="sequence" selected="false" />
<filter-element type="OBJECT" id="procedure" selected="false" />
<filter-element type="OBJECT" id="function" selected="false" />
<filter-element type="OBJECT" id="package" selected="false" />
<filter-element type="OBJECT" id="type" selected="false" />
<filter-element type="OBJECT" id="dimension" selected="false" />
<filter-element type="OBJECT" id="cluster" selected="false" />
<filter-element type="OBJECT" id="dblink" selected="false" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</basic-filter>
<extended-filter>
<filter-element type="RESERVED_WORD" id="keyword" selected="true" />
<filter-element type="RESERVED_WORD" id="function" selected="true" />
<filter-element type="RESERVED_WORD" id="parameter" selected="true" />
<filter-element type="RESERVED_WORD" id="datatype" selected="true" />
<filter-element type="RESERVED_WORD" id="exception" selected="true" />
<filter-element type="OBJECT" id="schema" selected="true" />
<filter-element type="OBJECT" id="user" selected="true" />
<filter-element type="OBJECT" id="role" selected="true" />
<filter-element type="OBJECT" id="privilege" selected="true" />
<user-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</user-schema>
<public-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</public-schema>
<any-schema>
<filter-element type="OBJECT" id="table" selected="true" />
<filter-element type="OBJECT" id="view" selected="true" />
<filter-element type="OBJECT" id="materialized view" selected="true" />
<filter-element type="OBJECT" id="index" selected="true" />
<filter-element type="OBJECT" id="constraint" selected="true" />
<filter-element type="OBJECT" id="trigger" selected="true" />
<filter-element type="OBJECT" id="synonym" selected="true" />
<filter-element type="OBJECT" id="sequence" selected="true" />
<filter-element type="OBJECT" id="procedure" selected="true" />
<filter-element type="OBJECT" id="function" selected="true" />
<filter-element type="OBJECT" id="package" selected="true" />
<filter-element type="OBJECT" id="type" selected="true" />
<filter-element type="OBJECT" id="dimension" selected="true" />
<filter-element type="OBJECT" id="cluster" selected="true" />
<filter-element type="OBJECT" id="dblink" selected="true" />
</any-schema>
</extended-filter>
</filters>
<sorting enabled="true">
<sorting-element type="RESERVED_WORD" id="keyword" />
<sorting-element type="RESERVED_WORD" id="datatype" />
<sorting-element type="OBJECT" id="column" />
<sorting-element type="OBJECT" id="table" />
<sorting-element type="OBJECT" id="view" />
<sorting-element type="OBJECT" id="materialized view" />
<sorting-element type="OBJECT" id="index" />
<sorting-element type="OBJECT" id="constraint" />
<sorting-element type="OBJECT" id="trigger" />
<sorting-element type="OBJECT" id="synonym" />
<sorting-element type="OBJECT" id="sequence" />
<sorting-element type="OBJECT" id="procedure" />
<sorting-element type="OBJECT" id="function" />
<sorting-element type="OBJECT" id="package" />
<sorting-element type="OBJECT" id="type" />
<sorting-element type="OBJECT" id="dimension" />
<sorting-element type="OBJECT" id="cluster" />
<sorting-element type="OBJECT" id="dblink" />
<sorting-element type="OBJECT" id="schema" />
<sorting-element type="OBJECT" id="role" />
<sorting-element type="OBJECT" id="user" />
<sorting-element type="RESERVED_WORD" id="function" />
<sorting-element type="RESERVED_WORD" id="parameter" />
</sorting>
<format>
<enforce-code-style-case value="true" />
</format>
</code-completion-settings>
<execution-engine-settings>
<statement-execution>
<fetch-block-size value="100" />
<execution-timeout value="20" />
<debug-execution-timeout value="600" />
<focus-result value="false" />
<prompt-execution value="false" />
</statement-execution>
<script-execution>
<command-line-interfaces />
<execution-timeout value="300" />
</script-execution>
<method-execution>
<execution-timeout value="30" />
<debug-execution-timeout value="600" />
<parameter-history-size value="10" />
</method-execution>
</execution-engine-settings>
<operation-settings>
<transactions>
<uncommitted-changes>
<on-project-close value="ASK" />
<on-disconnect value="ASK" />
<on-autocommit-toggle value="ASK" />
</uncommitted-changes>
<multiple-uncommitted-changes>
<on-commit value="ASK" />
<on-rollback value="ASK" />
</multiple-uncommitted-changes>
</transactions>
<session-browser>
<disconnect-session value="ASK" />
<kill-session value="ASK" />
<reload-on-filter-change value="false" />
</session-browser>
<compiler>
<compile-type value="KEEP" />
<compile-dependencies value="ASK" />
<always-show-controls value="false" />
</compiler>
<debugger>
<debugger-type value="JDBC" />
<use-generic-runners value="true" />
</debugger>
</operation-settings>
<ddl-file-settings>
<extensions>
<mapping file-type-id="VIEW" extensions="vw" />
<mapping file-type-id="TRIGGER" extensions="trg" />
<mapping file-type-id="PROCEDURE" extensions="prc" />
<mapping file-type-id="FUNCTION" extensions="fnc" />
<mapping file-type-id="PACKAGE" extensions="pkg" />
<mapping file-type-id="PACKAGE_SPEC" extensions="pks" />
<mapping file-type-id="PACKAGE_BODY" extensions="pkb" />
<mapping file-type-id="TYPE" extensions="tpe" />
<mapping file-type-id="TYPE_SPEC" extensions="tps" />
<mapping file-type-id="TYPE_BODY" extensions="tpb" />
</extensions>
<general>
<lookup-ddl-files value="true" />
<create-ddl-files value="false" />
<synchronize-ddl-files value="true" />
<use-qualified-names value="false" />
<make-scripts-rerunnable value="true" />
</general>
</ddl-file-settings>
<general-settings>
<regional-settings>
<date-format value="MEDIUM" />
<number-format value="UNGROUPED" />
<locale value="SYSTEM_DEFAULT" />
<use-custom-formats value="false" />
</regional-settings>
<environment>
<environment-types>
<environment-type id="development" name="Development" description="Development environment" color="-2430209/-12296320" readonly-code="false" readonly-data="false" />
<environment-type id="integration" name="Integration" description="Integration environment" color="-2621494/-12163514" readonly-code="true" readonly-data="false" />
<environment-type id="production" name="Production" description="Productive environment" color="-11574/-10271420" readonly-code="true" readonly-data="true" />
<environment-type id="other" name="Other" description="" color="-1576/-10724543" readonly-code="false" readonly-data="false" />
</environment-types>
<visibility-settings>
<connection-tabs value="true" />
<dialog-headers value="true" />
<object-editor-tabs value="true" />
<script-editor-tabs value="false" />
<execution-result-tabs value="true" />
</visibility-settings>
</environment>
</general-settings>
</component>
<component name="DBNavigator.Project.StatementExecutionManager">
<execution-variables />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="JSX" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/moecube-console-web.iml" filepath="$PROJECT_DIR$/.idea/moecube-console-web.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectTasksOptions">
<TaskOptions isEnabled="false">
<option name="arguments" value="--no-color $FileName$" />
<option name="checkSyntaxErrors" value="true" />
<option name="description" />
<option name="exitCodeBehavior" value="ERROR" />
<option name="fileExtension" value="less" />
<option name="immediateSync" value="true" />
<option name="name" value="Less" />
<option name="output" value="$FileNameWithoutExtension$.css" />
<option name="outputFilters">
<array>
<FilterInfo>
<option name="description" value="lessc error format" />
<option name="name" value="lessc" />
<option name="regExp" value="$MESSAGE$\Q in \E$FILE_PATH$\Q on line \E$LINE$\Q, column \E$COLUMN$" />
</FilterInfo>
</array>
</option>
<option name="outputFromStdout" value="true" />
<option name="program" value="" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="false" />
<option name="workingDir" value="$FileDir$" />
<envs />
</TaskOptions>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="7dc474d0-9fc0-4b76-8c2f-3c98df702116" name="Default" comment="">
<change type="DELETED" beforePath="$PROJECT_DIR$/src/components/Example.js" afterPath="" />
<change type="MOVED" beforePath="$PROJECT_DIR$/.roadhogrc" afterPath="$PROJECT_DIR$/.roadhogrc.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.eslintrc" afterPath="$PROJECT_DIR$/.eslintrc" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/package.json" afterPath="$PROJECT_DIR$/package.json" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/public/index.html" afterPath="$PROJECT_DIR$/public/index.html" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/components/App/Create.js" afterPath="$PROJECT_DIR$/src/components/App/Create.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/components/Common/Nav.js" afterPath="$PROJECT_DIR$/src/components/Common/Nav.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/index.js" afterPath="$PROJECT_DIR$/src/index.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/models/App.js" afterPath="$PROJECT_DIR$/src/models/App.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/models/Apps.js" afterPath="$PROJECT_DIR$/src/models/Apps.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/router.js" afterPath="$PROJECT_DIR$/src/router.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/routes/AppDetail.js" afterPath="$PROJECT_DIR$/src/routes/AppDetail.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/routes/AppDetail.less" afterPath="$PROJECT_DIR$/src/routes/AppDetail.less" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/routes/Entry.js" afterPath="$PROJECT_DIR$/src/routes/Entry.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/utils/request.js" afterPath="$PROJECT_DIR$/src/utils/request.js" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/yarn.lock" afterPath="$PROJECT_DIR$/yarn.lock" />
</list>
<ignored path="$PROJECT_DIR$/.tmp/" />
<ignored path="$PROJECT_DIR$/temp/" />
<ignored path="$PROJECT_DIR$/tmp/" />
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
<component name="FavoritesManager">
<favorites_list name="moecube-console-web" />
</component>
<component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
<file leaf-file-name="AppDetail.js" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/routes/AppDetail.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="798">
<caret line="701" column="40" lean-forward="false" selection-start-line="701" selection-start-column="40" selection-end-line="701" selection-end-column="40" />
<folding>
<element signature="e#0#26#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="FindInProjectRecents">
<findStrings>
<find>for</find>
<find>f</find>
<find>.update({ $set: { ...data }}).exec()</find>
<find>fo</find>
<find>format</find>
<find>formatm</find>
<find>formatme</find>
<find>cate</find>
<find>category</find>
<find>news</find>
<find>s</find>
<find>spin</find>
<find>&lt;</find>
<find>&lt;Sp</find>
<find>&lt;Spin</find>
<find>i</find>
<find>isMoun</find>
<find>isMounte</find>
<find>isMounted</find>
<find>isdanger</find>
<find>remove</find>
<find>width=&quot;100%&quot; height=&quot;100%&quot;</find>
<find>radio</find>
<find>console</find>
<find>pack</find>
<find>upload</find>
</findStrings>
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="IdeDocumentHistory">
<option name="CHANGED_PATHS">
<list>
<option value="$PROJECT_DIR$/src/models/Common.js" />
<option value="$PROJECT_DIR$/src/models/App.js" />
<option value="$PROJECT_DIR$/src/components/App/Create.js" />
<option value="$PROJECT_DIR$/src/router.js" />
<option value="$PROJECT_DIR$/.roadhogrc" />
<option value="$PROJECT_DIR$/public/index.html" />
<option value="$PROJECT_DIR$/src/components/Common/Nav.js" />
<option value="$PROJECT_DIR$/.eslintrc" />
<option value="$PROJECT_DIR$/src/utils/request.js" />
<option value="$PROJECT_DIR$/src/index.js" />
<option value="$PROJECT_DIR$/src/routes/Entry.js" />
<option value="$PROJECT_DIR$/src/models/Apps.js" />
<option value="$PROJECT_DIR$/src/routes/AppDetail.less" />
<option value="$PROJECT_DIR$/src/routes/AppDetail.js" />
</list>
</option>
</component>
<component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
<component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER">
<package-json value="$PROJECT_DIR$/package.json" />
</component>
<component name="JsGulpfileManager">
<detection-done>true</detection-done>
<sorting>DEFINITION_ORDER</sorting>
</component>
<component name="NodeModulesDirectoryManager">
<handled-path value="$PROJECT_DIR$/node_modules" />
</component>
<component name="ProjectFrameBounds">
<option name="x" value="235" />
<option name="y" value="58" />
<option name="width" value="1383" />
<option name="height" value="968" />
</component>
<component name="ProjectView">
<navigator currentView="ProjectPane" proportions="" version="1">
<flattenPackages />
<showMembers />
<showModules />
<showLibraryContents />
<hideEmptyPackages />
<abbreviatePackageNames />
<autoscrollToSource />
<autoscrollFromSource />
<sortByType />
<manualOrder />
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scratches" />
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="moecube-console-web" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="moecube-console-web" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="moecube-console-web" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="moecube-console-web" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
</panes>
</component>
<component name="PropertiesComponent">
<property name="WebServerToolWindowFactoryState" value="false" />
<property name="HbShouldOpenHtmlAsHb" value="" />
<property name="node.js.path.for.package.eslint" value="project" />
<property name="nodejs_interpreter_path" value="/usr/local/bin/node" />
<property name="node.js.selected.package.eslint" value="$PROJECT_DIR$/node_modules/eslint" />
<property name="node.js.path.for.package.standard" value="project" />
<property name="node.js.selected.package.standard" value="" />
</component>
<component name="RecentsManager">
<key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$" />
</key>
</component>
<component name="RunDashboard">
<option name="ruleStates">
<list>
<RuleState>
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
</RuleState>
<RuleState>
<option name="name" value="StatusDashboardGroupingRule" />
</RuleState>
</list>
</option>
</component>
<component name="RunManager">
<configuration default="true" type="DartCommandLineRunConfigurationType" factoryName="Dart Command Line Application">
<method />
</configuration>
<configuration default="true" type="DartTestRunConfigurationType" factoryName="Dart Test">
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerJest" factoryName="Jest">
<node-interpreter value="project" />
<working-dir value="" />
<envs />
<scope-kind value="ALL" />
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerKarma" factoryName="Karma">
<config-file value="" />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="JavaScriptTestRunnerProtractor" factoryName="Protractor">
<config-file value="" />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="JavascriptDebugType" factoryName="JavaScript Debug">
<method />
</configuration>
<configuration default="true" type="NodeJSConfigurationType" factoryName="Node.js" path-to-node="project" working-dir="">
<method />
</configuration>
<configuration default="true" type="cucumber.js" factoryName="Cucumber.js">
<option name="cucumberJsArguments" value="" />
<option name="executablePath" />
<option name="filePath" />
<method />
</configuration>
<configuration default="true" type="js.build_tools.gulp" factoryName="Gulp.js">
<method />
</configuration>
<configuration default="true" type="js.build_tools.npm" factoryName="npm">
<command value="run" />
<scripts />
<node-interpreter value="project" />
<envs />
<method />
</configuration>
<configuration default="true" type="mocha-javascript-test-runner" factoryName="Mocha">
<node-interpreter>project</node-interpreter>
<node-options />
<working-directory />
<pass-parent-env>true</pass-parent-env>
<envs />
<ui />
<extra-mocha-options />
<test-kind>DIRECTORY</test-kind>
<test-directory />
<recursive>false</recursive>
<method />
</configuration>
</component>
<component name="ShelveChangesManager" show_recycled="false">
<option name="remove_strategy" value="false" />
</component>
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="7dc474d0-9fc0-4b76-8c2f-3c98df702116" name="Default" comment="" />
<created>1492397512644</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1492397512644</updated>
<workItem from="1492397516564" duration="4541000" />
<workItem from="1492407287300" duration="13890000" />
</task>
<servers />
</component>
<component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="18431000" />
</component>
<component name="ToolWindowManager">
<frame x="235" y="58" width="1383" height="968" extended-state="0" />
<editor active="true" />
<layout>
<window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
<window_info id="DB Browser" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32966226" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="DB Execution Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="npm" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32966226" sideWeight="0.5" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32990867" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33333334" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="TypeScript" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.2572707" sideWeight="0.49315068" order="0" side_tool="false" content_ui="combo" />
<window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.24981357" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25354213" sideWeight="0.5068493" order="2" side_tool="true" content_ui="tabs" />
<window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
<window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout>
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="processedProjectFiles" value="true" />
<option name="exactExcludedFiles">
<list>
<option value="$PROJECT_DIR$/../moecube-console-backend/src/types.js" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/types.js.map" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/models/Iridium.js.map" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/models/Iridium.js" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/models/Package.js" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/models/Package.js.map" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/routes/upload.js.map" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/routes/upload.js" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/utils.js.map" />
<option value="$PROJECT_DIR$/../moecube-console-backend/src/utils.js" />
</list>
</option>
</component>
<component name="VcsContentAnnotationSettings">
<option name="myLimit" value="2678400000" />
</component>
<component name="XDebuggerManager">
<breakpoint-manager />
<watches-manager />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/src/index.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="162">
<caret line="14" column="3" lean-forward="false" selection-start-line="14" selection-start-column="3" selection-end-line="14" selection-end-column="3" />
<folding>
<element signature="e#0#33#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/package.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.roadhogrc.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="15" column="61" lean-forward="true" selection-start-line="15" selection-start-column="61" selection-end-line="15" selection-end-column="61" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/router.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="54">
<caret line="9" column="0" lean-forward="true" selection-start-line="9" selection-start-column="0" selection-end-line="9" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Apps.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Entry.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="324">
<caret line="25" column="1" lean-forward="true" selection-start-line="25" selection-start-column="1" selection-end-line="25" selection-end-column="1" />
<folding>
<element signature="e#0#26#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/Common/Nav.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="108">
<caret line="9" column="10" lean-forward="true" selection-start-line="9" selection-start-column="10" selection-end-line="9" selection-end-column="10" />
<folding>
<element signature="e#0#26#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/models/Apps.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="918">
<caret line="53" column="56" lean-forward="true" selection-start-line="53" selection-start-column="56" selection-end-line="53" selection-end-column="56" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/public/index.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="288">
<caret line="16" column="0" lean-forward="true" selection-start-line="16" selection-start-column="0" selection-end-line="16" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/dist/index.css">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="252">
<caret line="0" column="1627" lean-forward="false" selection-start-line="0" selection-start-column="1627" selection-end-line="0" selection-end-column="1627" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Login.css">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/IndexPage.css">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/LoginCallback.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Login.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/models/Common.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="90">
<caret line="5" column="18" lean-forward="true" selection-start-line="5" selection-start-column="18" selection-end-line="5" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/models/user.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Apps/All.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-159">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#0#26#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Apps.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/App/Create.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="162">
<caret line="9" column="4" lean-forward="false" selection-start-line="9" selection-start-column="4" selection-end-line="9" selection-end-column="4" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/public/index.html">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="198">
<caret line="11" column="0" lean-forward="true" selection-start-line="11" selection-start-column="0" selection-end-line="11" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/app.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.roadhogrc.mock.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="54">
<caret line="3" column="0" lean-forward="true" selection-start-line="3" selection-start-column="0" selection-end-line="3" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/config.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="108">
<caret line="6" column="1" lean-forward="false" selection-start-line="6" selection-start-column="1" selection-end-line="6" selection-end-column="1" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/node_modules/dva/router.d.ts">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="108">
<caret line="6" column="9" lean-forward="false" selection-start-line="6" selection-start-column="9" selection-end-line="6" selection-end-column="9" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.roadhogrc.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="288">
<caret line="16" column="7" lean-forward="true" selection-start-line="16" selection-start-column="7" selection-end-line="16" selection-end-column="7" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/Example.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="180">
<caret line="10" column="21" lean-forward="true" selection-start-line="10" selection-start-column="21" selection-end-line="10" selection-end-column="21" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/Common/Nav.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="176">
<caret line="25" column="12" lean-forward="true" selection-start-line="25" selection-start-column="12" selection-end-line="25" selection-end-column="12" />
<folding>
<element signature="e#0#26#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/components/Common/EditableCell.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="684">
<caret line="38" column="20" lean-forward="true" selection-start-line="38" selection-start-column="20" selection-end-line="38" selection-end-column="20" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/index.less">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/package.json">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/.eslintrc">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="90">
<caret line="5" column="34" lean-forward="true" selection-start-line="5" selection-start-column="34" selection-end-line="5" selection-end-column="34" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/router.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="108">
<caret line="12" column="41" lean-forward="true" selection-start-line="12" selection-start-column="41" selection-end-line="12" selection-end-column="41" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/utils/request.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="252">
<caret line="14" column="46" lean-forward="true" selection-start-line="14" selection-start-column="46" selection-end-line="14" selection-end-column="46" />
<folding>
<element signature="e#0#30#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/index.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="144">
<caret line="13" column="26" lean-forward="true" selection-start-line="13" selection-start-column="26" selection-end-line="13" selection-end-column="26" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/models/App.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="252">
<caret line="14" column="14" lean-forward="true" selection-start-line="14" selection-start-column="14" selection-end-line="14" selection-end-column="14" />
<folding>
<element signature="e#0#39#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/dist/index.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="18">
<caret line="12" column="19201" lean-forward="false" selection-start-line="12" selection-start-column="19201" selection-end-line="12" selection-end-column="19201" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/node_modules/antd/lib/tabs/index.d.ts">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="220">
<caret line="34" column="21" lean-forward="false" selection-start-line="34" selection-start-column="21" selection-end-line="34" selection-end-column="21" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/models/Apps.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="593">
<caret line="54" column="38" lean-forward="true" selection-start-line="54" selection-start-column="38" selection-end-line="54" selection-end-column="38" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/Entry.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="15" column="4" lean-forward="true" selection-start-line="15" selection-start-column="4" selection-end-line="15" selection-end-column="4" />
<folding>
<element signature="e#0#26#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/AppDetail.less">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="108">
<caret line="6" column="26" lean-forward="true" selection-start-line="6" selection-start-column="26" selection-end-line="6" selection-end-column="26" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/IndexPage.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="270">
<caret line="17" column="23" lean-forward="false" selection-start-line="17" selection-start-column="23" selection-end-line="17" selection-end-column="23" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/node_modules/antd/lib/input/Input.d.ts">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="124">
<caret line="60" column="6" lean-forward="true" selection-start-line="60" selection-start-column="6" selection-end-line="60" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/node_modules/antd/lib/form/Form.d.ts">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="187">
<caret line="73" column="21" lean-forward="false" selection-start-line="73" selection-start-column="21" selection-end-line="73" selection-end-column="21" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/src/routes/AppDetail.js">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="798">
<caret line="701" column="40" lean-forward="false" selection-start-line="701" selection-start-column="40" selection-end-line="701" selection-end-column="40" />
<folding>
<element signature="e#0#26#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</component>
</project>
\ No newline at end of file
{
export default {
"entry": "src/index.js",
"env": {
"development": {
"extraBabelPlugins": [
"dva-hmr",
"transform-runtime",
"babel-plugin-transform-decorators-legacy",
["import", { "libraryName": "antd", "style": "css" }]
]
},
"production": {
"extraBabelPlugins": [
"transform-runtime",
"babel-plugin-transform-decorators-legacy",
["import", { "libraryName": "antd", "style": "css" }]
]
}
......
......@@ -3,15 +3,14 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dva Demo</title>
<link rel="stylesheet" href="index.css" />
<base href="/">
<link rel="stylesheet" href="index.css"/>
<link rel="icon" href="https://moecube.com/favicon.ico">
</head>
<body>
<div id="root"></div>
<script src="index.js"></script>
<script src="/index.js"></script>
</body>
</html>
import React from 'react';
import styles from './Create.css';
import { Button, Modal, Form, Input, Radio, Select, Spin } from 'antd';
import { connect } from 'dva'
const FormItem = Form.Item;
@connect(
(state, props) => {
const { loading } = state
return {
loading
}
}
)
class Create extends React.Component {
handleSubmit = (e) => {
......@@ -20,11 +29,11 @@ class Create extends React.Component {
}
handleSelectChange = (value) => {
}
render() {
const { visible, onCancel, form, isLoading } = this.props;
const { visible, onCancel, form, loading } = this.props;
const { getFieldDecorator } = form;
return (
......@@ -34,7 +43,7 @@ class Create extends React.Component {
okText="提交"
onCancel={onCancel}
onOk={this.handleSubmit}>
<Spin spinning={isLoading} delay={100} tip="提交中...">
<Spin spinning={loading.global} delay={100} tip="提交中...">
<Form vertical onSubmit={this.handleSubmit}>
<FormItem label="应用 ID (创建应用后无法修改)">
......@@ -56,7 +65,7 @@ class Create extends React.Component {
<FormItem
label="主要语言"
wrapperCol={{ span: 8 }}>
{getFieldDecorator('locale', {
rules: [{ required: true, message: '请至少选择一门主要语言' }],
onChange: this.handleSelectChange,
......@@ -65,13 +74,13 @@ class Create extends React.Component {
<Select.Option value="zh-CN">zh-CN</Select.Option>
<Select.Option value="zh-TW">zh-TW</Select.Option>
<Select.Option value="en-US">en-US</Select.Option>
<Select.Option value="ja-JP">ja-JP</Select.Option>
<Select.Option value="ja-JP">ja-JP</Select.Option>
</Select>
)}
</FormItem>
</Form>
</Spin>
</Spin>
</Modal>
);
}
......
......@@ -2,30 +2,44 @@ import React from 'react';
import styles from './Nav.less';
import { Layout, Menu, Icon, Breadcrumb } from 'antd';
import {Link} from 'dva/router'
import { FormattedMessage } from 'react-intl'
import {connect} from 'dva'
const { Header, Sider, Content, Footer } = Layout;
const SubMenu = Menu.SubMenu
function Nav({ collapsed, mode, dispatch }) {
return (
<Sider
collapsible
collapsed={collapsed}
onCollapse={() => dispatch({ type: 'Common/collapsed' })}>
<div className={styles.logo} />
<Menu theme="dark" mode={mode} defaultSelectedKeys={['0']}>
<Menu.Item key="0">
<Link to="/apps">
<Icon type="windows-o" />
@connect(
(state, props) => {
const {
Common: {collapsed, mode}
} = state
return {
collapsed,
mode
}
}
)
export default class Nav extends React.Component {
render(){
const { collapsed, mode, dispatch } = this.props
return (
<Sider
collapsible
collapsed={collapsed}
onCollapse={() => dispatch({ type: 'Common/collapsed' })}>
<div className={styles.logo} />
<Menu theme="dark" mode={mode} defaultSelectedKeys={['0']}>
<Menu.Item key="0">
<Link to="/apps">
<Icon type="windows-o" />
<span className="nav-next">
<FormattedMessage id="Apps"/>
</span>
</Link>
</Menu.Item>
</Menu>
</Sider>
);
apps
</span>
</Link>
</Menu.Item>
</Menu>
</Sider>
)
}
}
export default Nav;
import React from 'react';
const Example = () => {
return (
<div>
Example
</div>
);
};
Example.propTypes = {
};
export default Example;
import ReactDOM from 'react-dom';
import { browserHistory } from 'dva/router'
import {browserHistory} from 'dva/router'
import createLoading from 'dva-loading'
import {message} from 'antd'
import dva from 'dva';
import './index.less';
import { IntlProvider, addLocaleData } from 'react-intl';
// 1. Initialize
const app = dva({
history: browserHistory
onError: (error) => {
message.destroy();
message.error(error.message);
},
history: browserHistory,
});
app.model(require("./models/Apps"));
......@@ -24,6 +26,7 @@ app.model(require("./models/App"));
// 2. Plugins
// app.use({});
app.use(createLoading())
// 3. Model
// app.model(require('./models/example'));
......@@ -31,24 +34,10 @@ app.model(require("./models/App"));
// 4. Router
app.router(require('./router'));
// 5. Start
import en from 'react-intl/locale-data/en'
import zh from 'react-intl/locale-data/zh'
import localeData from '../i18n.json'
addLocaleData([...en, ...zh])
const language = navigator.language || (navigator.languages && navigator.languages[0]) || navigator.userLanguage;
const languageWithoutRegionCode = language.toLowerCase().split(/[_-]+/)[0];
const messages = localeData[languageWithoutRegionCode] || localeData[language] || localeData.zh;
const App = app.start()
ReactDOM.render(
<IntlProvider locale={ language } messages={ messages }>
<App />
</IntlProvider>,
<App />,
document.getElementById("root")
)
import { create } from '../services/Apps'
import {create} from '../services/Apps'
import {message} from 'antd'
export default {
namespace: 'App',
......@@ -23,13 +24,6 @@ export default {
isSubmit: true,
}
},
SubmitSuccess(state, action){
return {
...state,
isSubmit: false,
isCreate: false
}
},
onCancel(state, action) {
return {
...state,
......@@ -49,8 +43,8 @@ export default {
}
},
effects: {
*submit({ payload }, { call, put }){
yield put({ type: 'SubmitRequest', payload })
*submit({payload}, {call, put}){
yield put({type: 'SubmitRequest', payload})
const params = {
id: payload.id,
......@@ -59,13 +53,16 @@ export default {
}
}
const req = yield call(create, params)
if(req.data) {
yield put({ type: 'SubmitSuccess' })
yield put({ type: 'reset' })
// TODO: 成功提示
try {
const {data} = yield call(create, params)
if (data) {
yield put({type: 'SubmitSuccess'})
yield put({type: 'reset'})
message.info("i18n 创建成功")
}
} catch (error) {
message.error(error.message)
}
// TODO: 错误处理
}
},
subscriptions: {},
......
import { fetch, update } from '../services/Apps'
import {fetch, update} from '../services/Apps'
import * as crypto from 'crypto'
import {message} from 'antd'
import config from '../config'
......@@ -10,47 +11,65 @@ export default {
},
reducers: {
save(state, action) {
return {
...state,
return {
...state,
...action.payload
}
},
},
effects: {
*fetch({ payload }, { call, put }) {
const { data } = yield call(fetch, payload)
*fetch({payload}, {call, put}) {
let apps = {}
if(data && data.length > 0) {
data.map(app => {
apps[app["id"]] = app
})
try {
const {data} = yield call(fetch, payload)
let apps = {}
if (data && data.length > 0) {
data.map(app => {
apps[app["id"]] = app
})
}
yield put({type: 'save', payload: {apps}})
} catch (error) {
message.error(error.message)
}
yield put({ type: 'save', payload: { apps } })
},
*update({ payload }, {call, put}){
const { data } = yield call(update, payload)
*update({payload}, {call, put}){
try {
const {data} = yield call(update, payload)
if (data) {
yield put({ type: 'success'})
} else {
yield put({ type: 'faile' })
if (data) {
yield put({type: 'success'})
message.info("i18n success")
}
} catch (error) {
message.error(error.message)
}
},
*success({ payload }, { call, put}) {
yield put({ type: 'fetch' })
*addPackage({payload}, {call, put}){
try {
const {data} = yield call(update, payload)
if (data) {
yield put({type: 'success'})
}
} catch (error) {
message.error(error.message)
}
},
*success({payload}, {call, put}) {
yield put({type: 'fetch'})
}
},
subscriptions: {
setup({ dispatch, history }) {
return history.listen(({ pathname, query}) => {
setup({dispatch, history}) {
dispatch({type: 'fetch'})
if(/^apps/.test(pathname)) {
return history.listen(({pathname, query}) => {
dispatch({ type: 'fetch', payload: query})
} else if(pathname === '/login'){
if (pathname === '/login') {
let params = new URLSearchParams()
params.set('return_sso_url', config.returnSSO)
let payload = Buffer.from(params.toString()).toString('base64')
......@@ -59,7 +78,7 @@ export default {
params.set('sso', payload);
params.set('sig', crypto.createHmac('sha256', 'zsZv6LXHDwwtUAGa').update(payload).digest('hex'))
window.location.href=url
window.location.href = url
}
})
}
......
......@@ -11,11 +11,10 @@ function RouterConfig({ history }) {
return (
<Router history={history}>
<Route path="/" component={Entry} >
<Route path="apps" component={Apps} />
<Route path="apps/:id" component={AppDetail} />
<Route path="/apps/:id" component={AppDetail} />
<Route path="/apps" component={Apps} />
</Route>
<Route path="/loginCallback" component={LoginCallback} />
<Route path="*" component={() => <div>404</div>}/>
</Router>
);
}
......
import React from 'react';
import { connect } from 'dva';
import {connect} from 'dva';
import styles from './AppDetail.less';
import config from '../config'
import uuid from 'uuid'
import { Form, Input, Icon, Radio, Tag, Tooltip, Button, Select, Tabs, Upload, Modal, Table, Popconfirm, Row, Col, Card } from 'antd'
import {
Form,
Input,
Icon,
Radio,
Tag,
Tooltip,
Button,
Select,
Tabs,
Upload,
Modal,
Table,
Popconfirm,
Row,
Col,
Card,
Spin,
} from 'antd'
const FormItem = Form.Item;
const RadioButton = Radio.Button;
const RadioGroup = Radio.Group;
const Option = Select.Option;
const TabPane = Tabs.TabPane;
const Dragger = Upload.Dragger;
const confirm = Modal.confirm
const defCategory = ["game", "runtime", "emulator", "module"]
const defLocales = ["zh-CN", "zh-TW", "en-US", "ja-JP"]
const defPlatform = ["win32","darwin"]
const defPlatform = ["win32", "darwin"]
let defDevelopers = {}
let defPublishers = {}
let defNews = {}
......@@ -39,12 +55,11 @@ const defPackage = () => {
}
}
const defPackages = {
}
const defPackages = {}
const formItemLayout = {
labelCol: { span: 5 },
wrapperCol: { span: 24 },
labelCol: {span: 5},
wrapperCol: {span: 24},
}
const uploadProps = {
......@@ -57,9 +72,9 @@ const uploadProps = {
console.log(info.file, info.fileList);
}
if (status === 'done') {
message.success(`${info.file.name} file uploaded successfully.`);
// message.success(`${info.file.name} file uploaded successfully.`);
} else if (status === 'error') {
message.error(`${info.file.name} file upload failed.`);
// message.error(`${info.file.name} file upload failed.`);
}
},
}
......@@ -70,7 +85,7 @@ class AppDetail extends React.Component {
state = {
previewVisible: false,
previewImage: '',
icoList: [],
iconList: [],
coverList: [],
backgroundList: [],
isCreateNews: false,
......@@ -78,20 +93,19 @@ class AppDetail extends React.Component {
publishers: {},
news: {},
packages: [],
isDanger: false
};
componentWillReceiveProps(nextProps){
const { App:{ developers, publishers, news, packages = [] } } = nextProps
componentWillReceiveProps(nextProps) {
const {App: {developers, publishers, news, packages = []}} = nextProps
this.setState({
developers: {...defDevelopers, ...developers},
publishers: {...defPublishers, ...publishers},
packages: [...defPackages, ...packages],
news: {...defNews, ...news},
news: {...defNews, ...news},
})
}
handleCancel = () => this.setState({ previewVisible: false })
handleCancel = () => this.setState({previewVisible: false})
handlePreview = (file) => {
this.setState({
......@@ -100,37 +114,36 @@ class AppDetail extends React.Component {
});
}
handleChangeIco = ({ fileList }) => {
this.setState({ icoList: fileList })
this.handleUpdateImg({ fileList, field: 'icon'})
handleChangeIco = ({fileList}) => {
this.setState({iconList: fileList})
this.handleUpdateImg({fileList, field: 'icon'})
}
handleChangeCover = ({ fileList }) => {
this.setState({ coverList: fileList })
this.handleUpdateImg({ fileList, field: 'cover'})
handleChangeCover = ({fileList}) => {
this.setState({coverList: fileList})
this.handleUpdateImg({fileList, field: 'cover'})
}
handleChangeBackground = ({ fileList }) => {
this.setState({ backgroundList: fileList })
this.handleUpdateImg({ fileList, field: 'background'})
handleChangeBackground = ({fileList}) => {
this.setState({backgroundList: fileList})
this.handleUpdateImg({fileList, field: 'background'})
}
handleUpdateImg = ({ field, fileList }) => {
const { form, dispatch, params: { id }} = this.props
const [img] = fileList
if(img.status === 'done') {
handleUpdateImg = ({field, fileList}) => {
const {form, dispatch, params: {id}} = this.props
const [img] = fileList
if (img.status === 'done') {
const [res] = img.response
dispatch({type: "Apps/update", payload: {id, [field]: res.fileName }})
dispatch({type: "Apps/update", payload: {id, [field]: res.Key}})
}
}
onSubmitBase = (e) => {
const { form, dispatch, params: { id }} = this.props
const {form, dispatch, params: {id}} = this.props
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
const {category, homepage, conference, tags, locales} = values
dispatch({type: "Apps/update", payload: {id, category, homepage, conference, tags, locales}})
......@@ -139,13 +152,13 @@ class AppDetail extends React.Component {
}
onSubmitIntro = (e) => {
const { form, dispatch, params: { id }} = this.props
const {form, dispatch, params: {id}} = this.props
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
const {description, name, developers, publishers, news} = values
dispatch({type: "Apps/update", payload: {id, description, name, developers, publishers, news}})
......@@ -154,47 +167,63 @@ class AppDetail extends React.Component {
}
onSubmitManage = (e) => {
const { form, dispatch, params: { id }} = this.props
const {form, dispatch, params: {id}} = this.props
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
const {version, actions, references, dependencies} = values
Object.keys(actions).forEach((platform) => {
actions[platform] = JSON.parse(actions[platform])
})
dispatch({type: "Apps/update", payload: {id, version, actions, references, dependencies }})
dispatch({type: "Apps/update", payload: {id, version, actions, references, dependencies}})
}
});
}
onSubmitUpload = (e) => {
const { form, dispatch, params: { id }} = this.props
onSubmitUpload = (e, _pack) => {
const {form, dispatch, params: {id}} = this.props
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
let {upload: { packages }} = values
let {upload: {packages}} = values
const pack = packages.find(el => el.id == _pack.id)
dispatch({type: "Apps/update", payload: {id, packages}})
dispatch({type: "Apps/updatePackage", payload: {id, package: pack}})
}
});
}
onAddPackage = (e) => {
const {form, dispatch, params: {id}} = this.props
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
let {upload: {packages}} = values
dispatch({type: "Apps/addPackage", payload: {id, packages}})
}
});
}
onDeletePackage = (_id) => {
const { form, dispatch, params: { id }} = this.props
const {form, dispatch, params: {id}} = this.props
form.validateFieldsAndScroll((err, values) => {
if (!err) {
let {upload: { packages }} = values
let {upload: {packages}} = values
packages.splice(_id, 1)
dispatch({type: "Apps/update", payload: {id, packages}})
......@@ -206,8 +235,6 @@ class AppDetail extends React.Component {
this[action](targetKey);
}
add = async (targetKey) => {
let packages = this.state.packages
......@@ -218,25 +245,30 @@ class AppDetail extends React.Component {
packages
})
this.onSubmitUpload()
// this.onSubmitUpload()
this.onAddPackage()
}
remove = async (targetKey) => {
if(!this.props.isDanger) {
let {packages} = this.state
packages.splice(targetKey,1)
await this.setState({
packages
})
this.onDeletePackage(targetKey)
}
confirm({
title: '️警告',
content: '你真的确定要删除嘛?',
onOk: async () => {
let {packages} = this.state
packages.splice(targetKey, 1)
await this.setState({
packages
})
return this.onDeletePackage(targetKey)
},
})
}
onAddField = ({locale, field, data}) => {
let newField = Object.assign({}, this.state[field])
newField[locale].push(data)
this.setState({
......@@ -247,7 +279,7 @@ class AppDetail extends React.Component {
onDeleteField = ({locale, field, index}) => {
let newField = Object.assign({}, this.state[field])
newField[locale].splice(index,1)
newField[locale].splice(index, 1)
this.setState({
[field]: newField
......@@ -255,464 +287,508 @@ class AppDetail extends React.Component {
}
render() {
console.log(this.props, this.state)
const { form, App} = this.props
const { getFieldDecorator } = form
const { id, author, homepage, references={}, dependencies={}, description={}, actions={}, version={}, name={}, category={}, tags=[], locales=[], conference, icon, cover, background, } = App
const { publishers, developers, previewVisible, previewImage, icoList, coverList, backgroundList, isCreateNews, news, packages } = this.state
const {form, App, loading} = this.props
const {getFieldDecorator} = form
const {id, author, homepage, references = {}, dependencies = {}, description = {}, actions = {}, version = {}, name = {}, category, tags = [], locales = [], conference, icon, cover, background,} = App
const {publishers, developers, previewVisible, previewImage, iconList, coverList, backgroundList, isCreateNews, news, packages} = this.state
return (
<Tabs defaultActiveKey="1" className="app-detail-nav">
<TabPane tab={<span><Icon type="setting" /> 基本信息 </span>} key="1">
<div className={styles.form}>
<Form onSubmit={this.onSubmitBase}>
<div style={{ display: 'flex' }}>
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
<FormItem {...formItemLayout}>
{getFieldDecorator('icon', {
})(
<div className="clearfix">
<Upload
multiple={false}
action={`${config.apiRoot}/upload/image`}
listType="picture-card"
className="upload-icon"
fileList={icoList}
onChange={this.handleChangeIco}
onPreview={this.handlePreview}
>
{icoList.length >= 1 ? null :
<div>
<Icon type="plus" />
<div className="ant-upload-text">Icon</div>
</div>
}
</Upload>
</div>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator('cover', {
})(
<div className="clearfix">
<Upload
multiple={false}
action={`${config.apiRoot}/upload/image`}
listType="picture-card"
className="upload-icon"
fileList={coverList}
onChange={this.handleChangeCover}
onPreview={this.handlePreview}
>
{coverList.length >= 1 ? null :
<div>
<Icon type="plus" />
<div className="ant-upload-text">Cover</div>
</div>
}
</Upload>
</div>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator('background', {
})(
<div className="clearfix">
<Upload
multiple={false}
action={`${config.apiRoot}/upload/image`}
listType="picture-card"
className="upload-icon"
fileList={backgroundList}
onChange={this.handleChangeBackground}
onPreview={this.handlePreview}
>
{backgroundList.length >= 1 ? null :
<div>
<Icon type="plus" />
<div className="ant-upload-text">Background</div>
</div>
}
</Upload>
<Spin spinning={loading.global}>
<Tabs defaultActiveKey="1" className="app-detail-nav">
<TabPane tab={<span><Icon type="setting"/> 基本信息 </span>} key="1">
<div className={styles.form}>
<Form onSubmit={this.onSubmitBase}>
<div style={{display: 'flex'}}>
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
<img alt="example" style={{width: '100%'}} src={previewImage}/>
</Modal>
<FormItem {...formItemLayout}>
{getFieldDecorator('icon', {})(
<div className="clearfix">
<Upload
multiple={false}
action={`${config.apiRoot}/upload/image`}
listType="picture-card"
className="upload-icon"
fileList={iconList}
onChange={this.handleChangeIco}
onPreview={this.handlePreview}
>
{iconList.length >= 1 ? null :
icon ?
<img src={icon} width="100%" height="100%"/>
:
<div>
<Icon type="plus"/>
<div className="ant-upload-text">Cover</div>
</div>
}
</Upload>
</div>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator('cover', {})(
<div className="clearfix">
<Upload
multiple={false}
action={`${config.apiRoot}/upload/image`}
listType="picture-card"
className="upload-icon"
fileList={coverList}
onChange={this.handleChangeCover}
onPreview={this.handlePreview}
>
{coverList.length >= 1 ? null :
cover ?
<img src={cover} width="100%" height="100%"/>
:
<div>
<Icon type="plus"/>
<div className="ant-upload-text">Cover</div>
</div>
}
</Upload>
</div>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator('background', {})(
<div className="clearfix">
<Upload
multiple={false}
action={`${config.apiRoot}/upload/image`}
listType="picture-card"
className="upload-icon"
fileList={backgroundList}
onChange={this.handleChangeBackground}
onPreview={this.handlePreview}
>
{backgroundList.length >= 1 ? null :
background ?
<img src={background} width="100%" height="100%"/>
:
<div>
<Icon type="plus"/>
<div className="ant-upload-text">Cover</div>
</div>
}
</Upload>
</div>
)}
</FormItem>
</div>
)}
</FormItem>
</div>
<FormItem {...formItemLayout} label="游戏类别" >
{getFieldDecorator('category', {
initialValue: category
})(
<RadioGroup>
{defCategory.map((c,i) => {
return <RadioButton value={c} key={i}>{c}</RadioButton>
})}
</RadioGroup>
)}
</FormItem>
<FormItem
{...formItemLayout}
help="以 http:// 或 https:// 开头,没有可留空">
{getFieldDecorator('homepage', {
initialValue: homepage
})(
<Input addonBefore={<Icon type="home" />} placeholder="网站" />
)}
</FormItem>
<FormItem
{...formItemLayout}
help="游戏类应用通常与 ID 相同,其他类型的应用留空">
{getFieldDecorator('conference', {
initialValue: conference
})(
<Input addonBefore={<Icon type="message" />} placeholder="聊天室" />
)}
</FormItem>
<FormItem
{...formItemLayout}
help="JSON string[],不会写请联系 zh99998@gmail.com"
>
{getFieldDecorator('tags', {
initialValue: tags
})(
<Select tags style={{ width: '100%' }} placeholder="标签">
</Select>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator('locales', {
initialValue: locales
})(
<Select
tags
style={{ width: '100%' }}
placeholder="游戏支持的语言">
{defLocales.map((locale,i) => {
return <Select.Option key={i} value={locale}>{locale}</Select.Option>
})}
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
</Form>
</div>
</TabPane>
<TabPane tab={<span><Icon type="solution" />应用介绍</span>} key="2">
<div className={styles.form}>
<Tabs type="card" className="app-detail-nav">
{defLocales.map((locale,i) => {
return (
<TabPane tab={locale} key={i}>
<Form onSubmit={this.onSubmitIntro}>
<FormItem {...formItemLayout}>
{getFieldDecorator(`name[${locale}]`, {
initialValue: name[locale]
})(
<Input addonBefore={<Icon type="edit" />} placeholder="应用名称" />
)}
</FormItem>
<FormItem {...formItemLayout} >
{getFieldDecorator(`description[${locale}]`, {
initialValue: description[locale]
})(
<Input type="textarea" placeholder="应用介绍" autosize={{ minRows: 2}}/>
)}
</FormItem>
<Card title="开发者" extra={<a onClick={ () => this.onAddField({locale, field:'developers', data: { url:'', name: ''}})}>Add </a>}>
{developers[locale] && developers[locale].length > 0 && developers[locale].map((developer,index) => {
return (
<Form key={index}>
<FormItem {...formItemLayout}>
<Row gutter={24}>
<Col span={10}>
{getFieldDecorator(`developers[${locale}][${index}]["name"]`, {
initialValue: developer["name"]
})(
<Input addonBefore={<Icon type="user" />} placeholder="name" />
)}
</Col>
<Col span={10}>
{getFieldDecorator(`developers[${locale}][${index}]["url"]`, {
initialValue: developer["url"]
})(
<Input addonBefore={<Icon type="link" />} placeholder="url" />
)}
</Col>
<Col span={4}>
<a onClick={() => this.onDeleteField({locale, index, field: 'developers'})}>Delete</a>
</Col>
</Row>
</FormItem>
</Form>
)
})}
</Card>
<Card title="发行者" extra={<a onClick={ () => this.onAddField({locale, field:'publishers', data: { url:'', name: ''}})}>Add </a>}>
{publishers[locale] && publishers[locale].length > 0 && publishers[locale].map((publisher,index) => {
return (
<Form key={index}>
<FormItem {...formItemLayout}>
<Row gutter={24}>
<Col span={10}>
{getFieldDecorator(`publishers[${locale}][${index}]["name"]`, {
initialValue: publisher["name"]
})(
<Input addonBefore={<Icon type="user" />} placeholder="name" />
)}
</Col>
<Col span={10}>
{getFieldDecorator(`publishers[${locale}][${index}]["url"]`, {
initialValue: publisher["url"]
})(
<Input addonBefore={<Icon type="link" />} placeholder="url" />
)}
</Col>
<Col span={4}>
<a onClick={() => this.onDeleteField({locale, index, field: 'publishers'})}>Delete</a>
</Col>
</Row>
</FormItem>
</Form>
)
<FormItem {...formItemLayout} label="游戏类别">
{getFieldDecorator('category', {
initialValue: category
})(
<RadioGroup>
{defCategory.map((c, i) => {
return <RadioButton value={c} key={i}>{c}</RadioButton>
})}
</Card>
<Card title="新闻" extra={<a onClick={ () => this.onAddField({locale, field:'news', data: { url:'', title: '', text: ""}})}>Add </a>}>
{news[locale] && news[locale].length > 0 && news[locale].map((item,index) => {
return (
<Form key={index}>
<FormItem {...formItemLayout} >
{getFieldDecorator(`news[${locale}][${index}]["url"]`, {
initialValue: item["url"]
})(
<Input prefix={<Icon type="link" />} placeholder="url" />
)}
{getFieldDecorator(`news[${locale}][${index}]["title"]`, {
initialValue: item["title"]
})(
<Input prefix={<Icon type="edit" />} placeholder="title" />
)}
{getFieldDecorator(`news[${locale}][${index}]["text"]`, {
initialValue: item["text"]
})(
<Input type="textarea" prefix={<Icon type="edit" />} placeholder="text" />
)}
<a onClick={() => this.onDeleteField({locale, index, field: 'news'})}>Delete</a>
</FormItem>
</Form>
)
</RadioGroup>
)}
</FormItem>
<FormItem
{...formItemLayout}
help="以 http:// 或 https:// 开头,没有可留空">
{getFieldDecorator('homepage', {
initialValue: homepage
})(
<Input addonBefore={<Icon type="home"/>} placeholder="网站"/>
)}
</FormItem>
<FormItem
{...formItemLayout}
help="游戏类应用通常与 ID 相同,其他类型的应用留空">
{getFieldDecorator('conference', {
initialValue: conference
})(
<Input addonBefore={<Icon type="message"/>} placeholder="聊天室"/>
)}
</FormItem>
<FormItem
{...formItemLayout}
help="JSON string[],不会写请联系 zh99998@gmail.com"
>
{getFieldDecorator('tags', {
initialValue: tags
})(
<Select tags style={{width: '100%'}} placeholder="标签">
</Select>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator('locales', {
initialValue: locales
})(
<Select
tags
style={{width: '100%'}}
placeholder="游戏支持的语言">
{defLocales.map((locale, i) => {
return <Select.Option key={i} value={locale}>{locale}</Select.Option>
})}
</Card>
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
</Form>
</TabPane>
)
})}
</Tabs>
</div>
</TabPane>
<TabPane tab={<span><Icon type="save" />应用管理</span>} key="3">
<div className={styles.form}>
<Tabs type="card" className="app-detail-nav">
{defPlatform.map((platform,i) =>
<TabPane tab={platform} key={i}>
<Form onSubmit={this.onSubmitManage}>
<FormItem {...formItemLayout} help="version">
{getFieldDecorator(`version[${platform}]`, {
initialValue: version[platform]
})(
<Input addonBefore={<Icon type="info-circle-o" />} placeholder="版本号" />
)}
</FormItem>
<FormItem {...formItemLayout} help="actions">
{getFieldDecorator(`actions[${platform}]`, {
initialValue: actions[platform] && JSON.stringify(actions[platform], null, '\t')
})(
<Input type="textarea" addonBefore={<Icon type="info-circle-o" />} placeholder="actions" autosize/>
)}
</FormItem>
<FormItem {...formItemLayout} help="dependencies">
{getFieldDecorator(`dependencies[${platform}]`, {
initialValue: dependencies[platform]
})(
<Select tags style={{ width: '100%' }} placeholder="dependencies">
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} help="references">
{getFieldDecorator(`references[${platform}]`, {
initialValue: references[platform]
})(
<Select tags style={{ width: '100%' }} placeholder="references">
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
</Form>
</TabPane>
)}
</Tabs>
</div>
</TabPane>
</Form>
</div>
</TabPane>
<TabPane tab={<span><Icon type="save" />应用上传</span>} key="4">
<div className={styles.form}>
<Tabs type="editable-card" className="app-detail-nav" onEdit={this.onEdit}>
<TabPane tab={<span><Icon type="solution"/>应用介绍</span>} key="2">
<div className={styles.form}>
<Tabs type="card" className="app-detail-nav">
{packages && packages.map((pack,i) => {
if(pack) {
return (
<TabPane tab={pack.name || "New"} key={i} closable={false}>
<Form onSubmit={this.onSubmitUpload}>
{defLocales.map((locale, i) => {
<FormItem {...formItemLayout} help="id">
{getFieldDecorator(`upload["packages"][${i}]["id"]`, {
initialValue: pack["id"]
})(
<Input addonBefore={<Icon type="info-circle-o" />} placeholder="id" disabled />
)}
</FormItem>
<FormItem {...formItemLayout} help="name">
{getFieldDecorator(`upload["packages"][${i}]["name"]`, {
initialValue: pack["name"]
return (
<TabPane tab={locale} key={i}>
<Form onSubmit={this.onSubmitIntro}>
<FormItem {...formItemLayout}>
{getFieldDecorator(`name[${locale}]`, {
initialValue: name[locale]
})(
<Input addonBefore={<Icon type="info-circle-o" />} placeholder="name" />
<Input addonBefore={<Icon type="edit"/>} placeholder="应用名称"/>
)}
</FormItem>
<FormItem {...formItemLayout} help="version">
{getFieldDecorator(`upload["packages"][${i}]["version"]`, {
initialValue: pack["version"]
<FormItem {...formItemLayout} >
{getFieldDecorator(`description[${locale}]`, {
initialValue: description[locale]
})(
<Input addonBefore={<Icon type="info-circle-o" />} placeholder="版本号" />
<Input type="textarea" placeholder="应用介绍" autosize={{minRows: 2}}/>
)}
</FormItem>
<FormItem {...formItemLayout} help="platforms">
{getFieldDecorator(`upload["packages"][${i}]["platforms"]`, {
initialValue: pack["platforms"]
})(
<Select multiple style={{ width: '100%' }} placeholder="platforms">
{defPlatform.map((_platform,i) => {
return <Select.Option key={i} value={_platform}>{_platform}</Select.Option>
})}
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} help="locales">
{getFieldDecorator(`upload["packages"][${i}]["locales"]`, {
initialValue: pack["locales"]
})(
<Select multiple style={{ width: '100%' }} placeholder="locales">
{defLocales.map((_locales,i) => {
return <Select.Option key={i} value={_locales}>{_locales}</Select.Option>
})}
</Select>
)}
</FormItem>
<Card title="开发者" extra={<a onClick={ () => this.onAddField({
locale,
field: 'developers',
data: {url: '', name: ''}
})}>Add </a>}>
{developers[locale] && developers[locale].length > 0 && developers[locale].map((developer, index) => {
return (
<Form key={index}>
<FormItem {...formItemLayout}>
<Row gutter={24}>
<Col span={10}>
{getFieldDecorator(`developers[${locale}][${index}]["name"]`, {
initialValue: developer["name"]
})(
<Input addonBefore={<Icon type="user"/>} placeholder="name"/>
)}
</Col>
<Col span={10}>
{getFieldDecorator(`developers[${locale}][${index}]["url"]`, {
initialValue: developer["url"]
})(
<Input addonBefore={<Icon type="link"/>} placeholder="url"/>
)}
</Col>
<Col span={4}>
<a onClick={() => this.onDeleteField({
locale,
index,
field: 'developers'
})}>Delete</a>
</Col>
</Row>
</FormItem>
</Form>
)
})}
</Card>
<Card title="发行者" extra={<a onClick={ () => this.onAddField({
locale,
field: 'publishers',
data: {url: '', name: ''}
})}>Add </a>}>
{publishers[locale] && publishers[locale].length > 0 && publishers[locale].map((publisher, index) => {
return (
<Form key={index}>
<FormItem {...formItemLayout}>
<Row gutter={24}>
<Col span={10}>
{getFieldDecorator(`publishers[${locale}][${index}]["name"]`, {
initialValue: publisher["name"]
})(
<Input addonBefore={<Icon type="user"/>} placeholder="name"/>
)}
</Col>
<Col span={10}>
{getFieldDecorator(`publishers[${locale}][${index}]["url"]`, {
initialValue: publisher["url"]
})(
<Input addonBefore={<Icon type="link"/>} placeholder="url"/>
)}
</Col>
<Col span={4}>
<a onClick={() => this.onDeleteField({
locale,
index,
field: 'publishers'
})}>Delete</a>
</Col>
</Row>
</FormItem>
</Form>
)
})}
</Card>
<Card title="新闻" extra={<a onClick={ () => this.onAddField({
locale,
field: 'news',
data: {url: '', title: '', text: ""}
})}>Add </a>}>
{news[locale] && news[locale].length > 0 && news[locale].map((item, index) => {
return (
<Form key={index}>
<FormItem {...formItemLayout} >
{getFieldDecorator(`news[${locale}][${index}]["url"]`, {
initialValue: item["url"]
})(
<Input prefix={<Icon type="link"/>} placeholder="url"/>
)}
{getFieldDecorator(`news[${locale}][${index}]["title"]`, {
initialValue: item["title"]
})(
<Input prefix={<Icon type="edit"/>} placeholder="title"/>
)}
<FormItem {...formItemLayout}>
{getFieldDecorator(`upload["packages"][${i}]["upload"]`, {
})(
<Dragger
{...uploadProps}
action={`${config.apiRoot}/upload/packages/${pack["id"]}`}
disabled={pack.isNew}>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files</p>
</Dragger>
)}
</FormItem>
{getFieldDecorator(`news[${locale}][${index}]["text"]`, {
initialValue: item["text"]
})(
<Input type="textarea" prefix={<Icon type="edit"/>} placeholder="text"/>
)}
<a onClick={() => this.onDeleteField({locale, index, field: 'news'})}>Delete</a>
</FormItem>
</Form>
)
})}
</Card>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
</Form>
</TabPane>
)
} else {
return (
<TabPane tab={"!"} key={i} closable={true}>
<div>好像出了什么问题, 请联系xxxxxx</div>
</TabPane>
)
}
})}
</Tabs>
</div>
</TabPane>
</Tabs>
})}
</Tabs>
</div>
</TabPane>
<TabPane tab={<span><Icon type="save"/>应用管理</span>} key="3">
<div className={styles.form}>
<Tabs type="card" className="app-detail-nav">
{defPlatform.map((platform, i) =>
<TabPane tab={platform} key={i}>
<Form onSubmit={this.onSubmitManage}>
<FormItem {...formItemLayout} help="version">
{getFieldDecorator(`version[${platform}]`, {
initialValue: version[platform]
})(
<Input addonBefore={<Icon type="info-circle-o"/>} placeholder="版本号"/>
)}
</FormItem>
<FormItem {...formItemLayout} help="actions">
{getFieldDecorator(`actions[${platform}]`, {
initialValue: actions[platform] && JSON.stringify(actions[platform], null, '\t')
})(
<Input type="textarea" addonBefore={<Icon type="info-circle-o"/>} placeholder="actions"
autosize/>
)}
</FormItem>
<FormItem {...formItemLayout} help="dependencies">
{getFieldDecorator(`dependencies[${platform}]`, {
initialValue: dependencies[platform]
})(
<Select tags style={{width: '100%'}} placeholder="dependencies">
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} help="references">
{getFieldDecorator(`references[${platform}]`, {
initialValue: references[platform]
})(
<Select tags style={{width: '100%'}} placeholder="references">
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
</Form>
</TabPane>
)}
</Tabs>
</div>
</TabPane>
<TabPane tab={<span><Icon type="save"/>应用上传</span>} key="4">
<div className={styles.form}>
<Tabs type="editable-card" className="app-detail-nav" onEdit={this.onEdit}>
{packages && packages.map((pack, i) => {
if (pack) {
return (
<TabPane tab={pack.name || "New"} key={i} closable={packages.length > 1}>
<Form onSubmit={e => this.onSubmitUpload(e, pack)}>
<FormItem {...formItemLayout} help="id">
{getFieldDecorator(`upload["packages"][${i}]["id"]`, {
initialValue: pack["id"]
})(
<Input addonBefore={<Icon type="info-circle-o"/>} placeholder="id" disabled/>
)}
</FormItem>
<FormItem {...formItemLayout} help="name">
{getFieldDecorator(`upload["packages"][${i}]["name"]`, {
initialValue: pack["name"]
})(
<Input addonBefore={<Icon type="info-circle-o"/>} placeholder="name"/>
)}
</FormItem>
<FormItem {...formItemLayout} help="version">
{getFieldDecorator(`upload["packages"][${i}]["version"]`, {
initialValue: pack["version"]
})(
<Input addonBefore={<Icon type="info-circle-o"/>} placeholder="版本号"/>
)}
</FormItem>
<FormItem {...formItemLayout} help="platforms">
{getFieldDecorator(`upload["packages"][${i}]["platforms"]`, {
initialValue: pack["platforms"]
})(
<Select multiple style={{width: '100%'}} placeholder="platforms">
{defPlatform.map((_platform, i) => {
return <Select.Option key={i} value={_platform}>{_platform}</Select.Option>
})}
</Select>
)}
</FormItem>
<FormItem {...formItemLayout} help="locales">
{getFieldDecorator(`upload["packages"][${i}]["locales"]`, {
initialValue: pack["locales"]
})(
<Select multiple style={{width: '100%'}} placeholder="locales">
{defLocales.map((_locales, i) => {
return <Select.Option key={i} value={_locales}>{_locales}</Select.Option>
})}
</Select>
)}
</FormItem>
<FormItem {...formItemLayout}>
{getFieldDecorator(`upload["packages"][${i}]["upload"]`, {})(
<Tabs defaultActiveKey="1" size="small">
<TabPane tab="url上传" key="1">
{getFieldDecorator(`upload["packages"][${i}]["url"]`, {
// initialValue: pack["url"]
})(
<div>
<Input addonBefore={<Icon type="uplaad"/>} placeholder="url"/>
请确认输入的链接真实有效~
</div>
)}
</TabPane>
<TabPane tab="直接上传" key="2">
<Dragger
{...uploadProps}
action={`${config.apiRoot}/upload/packages/${pack["id"]}`}
disabled={pack.isNew}>
<p className="ant-upload-drag-icon">
<Icon type="inbox"/>
</p>
<p className="ant-upload-text">Click or drag file to this area to upload</p>
<p className="ant-upload-hint">Support for a single or bulk upload. Strictly
prohibit
from uploading company data or other band files</p>
</Dragger>
</TabPane>
</Tabs>
)}
</FormItem>
<FormItem {...formItemLayout} >
<div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button>
</div>
</FormItem>
</Form>
</TabPane>
)
} else {
return (
<TabPane tab={"!"} key={i} closable={true}>
<div>好像出了什么问题, 请联系xxxxxx</div>
</TabPane>
)
}
})}
</Tabs>
</div>
</TabPane>
</Tabs>
</Spin>
);
}
}
function mapStateToProps(state, props) {
const {params: { id }} = props
const {params: {id}} = props
const {
Apps: { apps }
Apps: {apps},
loading
} = state
const App = apps[id] || {}
return {
loading,
App
};
}
......
:global {
.app-detail-nav{
}
.ant-card {
margin: 2vh 0;
}
.app-detail-nav .ant-tabs-nav-scroll {
display: flex;
justify-content: center;
}
.ant-upload-select-picture-card i {
font-size: 28px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
font-size: 12px;
color: #666;
}
}
.wrapSubmit{
display: flex;
justify-content: center;
}
.form {
align-content: center;
padding: 0 5vw;
display: flex;
justify-content: center;
}
\ No newline at end of file
:global {
.ant-upload {
display: flex !important;
justify-content: center;
align-items:center;
padding: 0 !important;
}
.ant-upload-text {
margin-top: 0 !important;
}
.ant-card {
margin: 2vh 0;
}
.app-detail-nav .ant-tabs-nav-scroll {
display: flex;
justify-content: center;
}
.ant-upload-select-picture-card i {
font-size: 28px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
font-size: 12px;
color: #666;
}
}
.wrapSubmit{
display: flex;
justify-content: center;
}
.form {
align-content: center;
padding: 0 5vw;
display: flex;
justify-content: center;
}
import React from 'react';
import { connect } from 'dva';
import styles from './Entry.less';
import Nav from '../components/Common/Nav'
import { Router, Route, browserHistory } from 'dva/router';
import {Layout} from 'antd'
function Entry({ children, collapsed, mode, dispatch }) {
const NavProps = {
collapsed,
mode,
dispatch
}
function Entry({ children}) {
return (
<Layout style={{ flexDirection: 'row', minHeight: '100%'}}>
<Nav {...NavProps}/>
<Nav />
<Layout style={{ minHeight: '400px'}}>
{children}
</Layout>
......@@ -26,13 +17,7 @@ function Entry({ children, collapsed, mode, dispatch }) {
}
function mapStateToProps(state) {
const {
Common: {collapsed, mode}
} = state
return {
collapsed,
mode
};
return {}
}
export default connect(mapStateToProps)(Entry);
import fetch from 'dva/fetch';
import config from '../config'
import config from '../config';
function parseJSON(response) {
return response.json();
}
function checkStatus(response) {
async function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
let message;
try {
message = (await response.json()).message;
} catch (error) {
message = response.statusText;
}
const error = new Error(message);
error.response = response;
throw error;
}
......@@ -22,17 +29,20 @@ function checkStatus(response) {
* @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err"
*/
export default function request(url, options) {
url = `${config.apiRoot}${url}`
if(options && !options.headers && (options.method == 'POST' || options.method == 'PATCH')) {
options.headers = {
"content-type": "application/json"
}
export default function request(relativeUrl, options) {
const url = `${config.apiRoot}${relativeUrl}`;
if (options && !options.headers) {
Object.assign(options, {
headers: {
'content-type': 'application/json',
},
});
}
console.log(options);
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
.then(data => ({ data }))
.catch(err => ({ err }));
}
.then(data => ({data}));
// .catch(err => ({ err }));
};
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment