зеркало из https://github.com/github/vitess-gh.git
Some cleanup on the Node-related Go<->javascript API. (#2221)
- Make the first value of enums (the one that is equal to 0) to be the unknown one, so that it was considered a programming error. - Remove "omitempty" tag from fields where change from some value to empty value must be passed in an update to the web UI. - Add "omitempty" to Children because that's an important special use case. - Modify javascript to assume that name, state, style and message of an action is always there. - Modify javascript to work when 'children' value was not received.
This commit is contained in:
Родитель
ab58e1113e
Коммит
cac9ce496f
|
@ -68,7 +68,8 @@ func TestLongPolling(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("/poll/1 reading failed: %v", err)
|
||||
}
|
||||
if string(tree) != `{"nodes":[{"name":"name","path":"/uuid1","children":[],"lastChanged":143,"actions":null}]}` {
|
||||
if !strings.Contains(string(tree), `"name":"name"`) ||
|
||||
!strings.Contains(string(tree), `"path":"/uuid1"`) {
|
||||
t.Errorf("unexpected first result: %v", string(tree))
|
||||
}
|
||||
|
||||
|
|
|
@ -27,47 +27,56 @@ import (
|
|||
type NodeDisplay int
|
||||
|
||||
const (
|
||||
// NodeDisplayUnknown is an unknown value and should never be set.
|
||||
NodeDisplayUnknown NodeDisplay = 0
|
||||
|
||||
// NodeDisplayIndeterminate is a progress bar that doesn't have
|
||||
// a current value, but just shows movement.
|
||||
NodeDisplayIndeterminate NodeDisplay = 0
|
||||
NodeDisplayIndeterminate NodeDisplay = 1
|
||||
|
||||
// NodeDisplayDeterminate is a progress bar driven by the
|
||||
// Progress field.
|
||||
NodeDisplayDeterminate NodeDisplay = 1
|
||||
NodeDisplayDeterminate NodeDisplay = 2
|
||||
|
||||
// NodeDisplayNone shows no progress bar or status.
|
||||
NodeDisplayNone NodeDisplay = 2
|
||||
NodeDisplayNone NodeDisplay = 3
|
||||
)
|
||||
|
||||
// ActionState constants need to match node.ts.ActionState.
|
||||
type ActionState int
|
||||
|
||||
const (
|
||||
// ActionStateUnknown is an unknown value and should never be set.
|
||||
ActionStateUnknown ActionState = 0
|
||||
|
||||
// ActionStateEnabled is for when the action is enabled.
|
||||
ActionStateEnabled ActionState = 0
|
||||
ActionStateEnabled ActionState = 1
|
||||
|
||||
// ActionStateDisabled is for when the action is disabled.
|
||||
ActionStateDisabled ActionState = 1
|
||||
ActionStateDisabled ActionState = 2
|
||||
)
|
||||
|
||||
// ActionStyle constants need to match node.ts.ActionStyle.
|
||||
type ActionStyle int
|
||||
|
||||
const (
|
||||
// ActionStyleUnknown is an unknown value and should never be set.
|
||||
ActionStyleUnknown ActionStyle = 0
|
||||
|
||||
// ActionStyleNormal will just trigger the action.
|
||||
ActionStyleNormal ActionStyle = 0
|
||||
ActionStyleNormal ActionStyle = 1
|
||||
|
||||
// ActionStyleWarning will display a warning dialog to confirm
|
||||
// action with Action.Message.
|
||||
ActionStyleWarning ActionStyle = 1
|
||||
ActionStyleWarning ActionStyle = 2
|
||||
|
||||
// ActionStyleWaiting highlights to the user that the process
|
||||
// is waiting on the execution of the action.
|
||||
ActionStyleWaiting ActionStyle = 2
|
||||
ActionStyleWaiting ActionStyle = 3
|
||||
|
||||
// ActionStyleTriggered is a state where the button is greyed
|
||||
// out and cannot be pressed.
|
||||
ActionStyleTriggered ActionStyle = 3
|
||||
ActionStyleTriggered ActionStyle = 4
|
||||
)
|
||||
|
||||
// Node is the UI representation of a Workflow toplevel object, or of
|
||||
|
@ -102,24 +111,24 @@ type Node struct {
|
|||
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Children []*Node `json:"children"`
|
||||
Children []*Node `json:"children,omitempty"`
|
||||
LastChanged int64 `json:"lastChanged"`
|
||||
Progress int `json:"progress,omitempty"`
|
||||
ProgressMessage string `json:"progressMsg,omitempty"`
|
||||
State workflowpb.WorkflowState `json:"state,omitempty"`
|
||||
Progress int `json:"progress"`
|
||||
ProgressMessage string `json:"progressMsg"`
|
||||
State workflowpb.WorkflowState `json:"state"`
|
||||
Display NodeDisplay `json:"display,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Log string `json:"log,omitempty"`
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
Message string `json:"message"`
|
||||
Log string `json:"log"`
|
||||
Disabled bool `json:"disabled"`
|
||||
Actions []*Action `json:"actions"`
|
||||
}
|
||||
|
||||
// Action must match node.ts Action.
|
||||
type Action struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Name string `json:"name"`
|
||||
State ActionState `json:"state,omitempty"`
|
||||
Style ActionStyle `json:"style,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Update is the data structure we send on the websocket or on the
|
||||
|
|
|
@ -73,7 +73,7 @@ func TestNodeManagerWithRoot(t *testing.T) {
|
|||
result, ok = <-notifications
|
||||
if !ok ||
|
||||
!strings.Contains(string(result), `"name":"name2"`) ||
|
||||
!strings.Contains(string(result), `"children":[]`) || // FIXME(alainjobart) this should be true, we're not changing the children.
|
||||
strings.Contains(string(result), `"children":[]`) ||
|
||||
strings.Contains(string(result), `"fullUpdate":true`) {
|
||||
t.Errorf("unexpected notification: %v %v", ok, string(result))
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ func TestWebSocket(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatalf("WebSocket first read failed: %v", err)
|
||||
}
|
||||
if string(tree) != `{"nodes":[{"name":"name","path":"/uuid1","children":[],"lastChanged":143,"actions":null}]}` {
|
||||
if !strings.Contains(string(tree), `"name":"name"`) ||
|
||||
!strings.Contains(string(tree), `"path":"/uuid1"`) {
|
||||
t.Errorf("unexpected first result: %v", string(tree))
|
||||
}
|
||||
|
||||
|
|
|
@ -28,5 +28,5 @@
|
|||
</head>
|
||||
<body class="flex-column">
|
||||
<vt-app-root class="flex-column flex-grow">Loading...</vt-app-root>
|
||||
<script type="text/javascript" src="inline.js"></script><script type="text/javascript" src="styles.07f8743f5392cfdfbcb5.bundle.js"></script><script type="text/javascript" src="main.b02cdae8978945277038.bundle.js"></script></body>
|
||||
<script type="text/javascript" src="inline.js"></script><script type="text/javascript" src="styles.07f8743f5392cfdfbcb5.bundle.js"></script><script type="text/javascript" src="main.ab14518241846dfc91ba.bundle.js"></script></body>
|
||||
</html>
|
||||
|
|
|
@ -1 +1 @@
|
|||
!function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,c){for(var _,a,i,u=0,p=[];u<t.length;u++)a=t[u],n[a]&&p.push(n[a][0]),n[a]=0;for(_ in o)if(Object.prototype.hasOwnProperty.call(o,_)){var f=o[_];switch(typeof f){case"object":e[_]=function(r){var t=r.slice(1),n=r[0];return function(r,o,c){e[n].apply(this,[r,o,c].concat(t))}}(f);break;case"function":e[_]=f;break;default:e[_]=e[f]}}for(r&&r(t,o,c);p.length;)p.shift()();if(c)for(u=0;u<c.length;u++)i=__webpack_require__(__webpack_require__.s=c[u]);return i};var t={},n={2:0};__webpack_require__.e=function(e){function onScriptComplete(){t.onerror=t.onload=null,clearTimeout(o);var r=n[e];0!==r&&(r&&r[1](new Error("Loading chunk "+e+" failed.")),n[e]=void 0)}if(0===n[e])return Promise.resolve();if(n[e])return n[e][2];var r=document.getElementsByTagName("head")[0],t=document.createElement("script");t.type="text/javascript",t.charset="utf-8",t.async=!0,t.timeout=12e4,t.src=__webpack_require__.p+""+e+"."+{0:"b02cdae8978945277038",1:"07f8743f5392cfdfbcb5"}[e]+".chunk.js";var o=setTimeout(onScriptComplete,12e4);t.onerror=t.onload=onScriptComplete,r.appendChild(t);var c=new Promise(function(r,t){n[e]=[r,t]});return n[e][2]=c},__webpack_require__.m=e,__webpack_require__.c=t,__webpack_require__.i=function(e){return e},__webpack_require__.d=function(e,r,t){Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,"a",r),r},__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},__webpack_require__.p="",__webpack_require__.oe=function(e){throw console.error(e),e}}(function(e){for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))switch(typeof e[r]){case"function":break;case"object":e[r]=function(r){var t=r.slice(1),n=e[r[0]];return function(e,r,o){n.apply(this,[e,r,o].concat(t))}}(e[r]);break;default:e[r]=e[e[r]]}return e}([]));
|
||||
!function(e){function __webpack_require__(r){if(t[r])return t[r].exports;var n=t[r]={i:r,l:!1,exports:{}};return e[r].call(n.exports,n,n.exports,__webpack_require__),n.l=!0,n.exports}var r=window.webpackJsonp;window.webpackJsonp=function(t,o,c){for(var _,a,i,u=0,p=[];u<t.length;u++)a=t[u],n[a]&&p.push(n[a][0]),n[a]=0;for(_ in o)if(Object.prototype.hasOwnProperty.call(o,_)){var f=o[_];switch(typeof f){case"object":e[_]=function(r){var t=r.slice(1),n=r[0];return function(r,o,c){e[n].apply(this,[r,o,c].concat(t))}}(f);break;case"function":e[_]=f;break;default:e[_]=e[f]}}for(r&&r(t,o,c);p.length;)p.shift()();if(c)for(u=0;u<c.length;u++)i=__webpack_require__(__webpack_require__.s=c[u]);return i};var t={},n={2:0};__webpack_require__.e=function(e){function onScriptComplete(){t.onerror=t.onload=null,clearTimeout(o);var r=n[e];0!==r&&(r&&r[1](new Error("Loading chunk "+e+" failed.")),n[e]=void 0)}if(0===n[e])return Promise.resolve();if(n[e])return n[e][2];var r=document.getElementsByTagName("head")[0],t=document.createElement("script");t.type="text/javascript",t.charset="utf-8",t.async=!0,t.timeout=12e4,t.src=__webpack_require__.p+""+e+"."+{0:"ab14518241846dfc91ba",1:"07f8743f5392cfdfbcb5"}[e]+".chunk.js";var o=setTimeout(onScriptComplete,12e4);t.onerror=t.onload=onScriptComplete,r.appendChild(t);var c=new Promise(function(r,t){n[e]=[r,t]});return n[e][2]=c},__webpack_require__.m=e,__webpack_require__.c=t,__webpack_require__.i=function(e){return e},__webpack_require__.d=function(e,r,t){Object.defineProperty(e,r,{configurable:!1,enumerable:!0,get:t})},__webpack_require__.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return __webpack_require__.d(r,"a",r),r},__webpack_require__.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},__webpack_require__.p="",__webpack_require__.oe=function(e){throw console.error(e),e}}(function(e){for(var r in e)if(Object.prototype.hasOwnProperty.call(e,r))switch(typeof e[r]){case"function":break;case"object":e[r]=function(r){var t=r.slice(1),n=e[r[0]];return function(e,r,o){n.apply(this,[e,r,o].concat(t))}}(e[r]);break;default:e[r]=e[e[r]]}return e}([]));
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Двоичный файл не отображается.
Двоичные данные
web/vtctld2/app/main.b02cdae8978945277038.bundle.js.gz
Двоичные данные
web/vtctld2/app/main.b02cdae8978945277038.bundle.js.gz
Двоичный файл не отображается.
|
@ -1,9 +1,11 @@
|
|||
export const enum ActionState {
|
||||
UNKNOWN,
|
||||
ENABLED,
|
||||
DISABLED,
|
||||
}
|
||||
|
||||
export const enum ActionStyle {
|
||||
UNKNOWN,
|
||||
NORMAL,
|
||||
WARNING, // Display warning dialog to confirm action with message
|
||||
WAITING, // Highlight to user that the process is waiting on action.
|
||||
|
@ -59,6 +61,7 @@ export const enum State {
|
|||
}
|
||||
|
||||
export const enum Display { // Only relevant if State is RUNNING.
|
||||
UNKNOWN,
|
||||
INDETERMINATE, // Only relevant if State is RUNNING.
|
||||
DETERMINATE,
|
||||
NONE // Even if Display is NONE progressMsg will still be shown.
|
||||
|
@ -95,12 +98,7 @@ export class Node {
|
|||
this.actions = [];
|
||||
if (changes.actions !== null) {
|
||||
for (let actionData of changes.actions) {
|
||||
let message = actionData.message ? actionData.message : '';
|
||||
let state = actionData.state ? actionData.state : ActionState.ENABLED;
|
||||
let style = actionData.style ? actionData.style : ActionStyle.NORMAL;
|
||||
if ('name' in actionData) {
|
||||
this.actions.push(new Action(actionData.name, state, style, message));
|
||||
}
|
||||
this.actions.push(new Action(actionData.name, actionData.state, actionData.style, actionData.message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ dolore magnam aliquam quaerat voluptatem.'});
|
|||
|
||||
// Need to update the target now.
|
||||
target.update(workflowData);
|
||||
if (workflowData.children !== null) {
|
||||
if ('children' in workflowData && workflowData.children !== null) {
|
||||
target.children = [];
|
||||
for (let childData of workflowData.children) {
|
||||
let child = this.recursiveWorkflowBuilder(childData);
|
||||
|
|
Загрузка…
Ссылка в новой задаче