diff --git a/ide/BUILD.gn b/ide/BUILD.gn deleted file mode 100644 index ad5fba00adfb78124448dae15e5edd0d0ad51619..0000000000000000000000000000000000000000 --- a/ide/BUILD.gn +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright (C) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -action("ts_build_sh") { - deps = [ "../trace_streamer:trace_streamer_port" ] - script = get_path_info("./build.sh", "abspath") - outputs = [ "$root_out_dir/developtools/smartperf_host/dist" ] - args = [ - rebase_path("."), - rebase_path("$root_out_dir/developtools/smartperf_host"), - ] -} diff --git a/ide/build.js b/ide/build.js index bf8795cb069f8b1789bf8b5d4918ddb426f93174..4ead05d71f42e8573b2ebd108268626ca284d5df 100644 --- a/ide/build.js +++ b/ide/build.js @@ -19,7 +19,7 @@ const childProcess = require('child_process'); const os = require('os'); const log4js = require('log4js'); -let compileServer = true; +const compileServer = true; const outDir = 'dist'; const sdkWams = [ @@ -66,35 +66,31 @@ function cpFile(from, to) { } function checkEnvironment() { - if (process.argv.slice(2)[0]) { - return true; - } else { - let goVersion = childProcess.execSync('go version', { - encoding: 'utf-8', - }); - log.info('go is', goVersion); - let nodeVersion = childProcess.execSync('node -v', { - encoding: 'utf-8', - }); - log.info('node version is', nodeVersion); - let tscVersion = childProcess.execSync('tsc -v', { - encoding: 'utf-8', - }); - log.info('tsc version is', tscVersion); - if (goVersion == '' || nodeVersion == '' || tscVersion == '') { - return false; - } - let traceStreamer = path.normalize(path.join(__dirname, '/bin')); - if (!checkDirExist(traceStreamer + '/trace_streamer_builtin.js')) { - log.error(traceStreamer + '/trace_streamer_builtin.js' + ' Must exist'); - return false; - } - if (!checkDirExist(traceStreamer + '/trace_streamer_builtin.wasm')) { - log.error(traceStreamer + '/trace_streamer_builtin.wasm' + ' Must exist'); - return false; - } - return true; + let goVersion = childProcess.execSync('go version', { + encoding: 'utf-8', + }); + log.info('go is', goVersion); + let nodeVersion = childProcess.execSync('node -v', { + encoding: 'utf-8', + }); + log.info('node version is', nodeVersion); + let tscVersion = childProcess.execSync('tsc -v', { + encoding: 'utf-8', + }); + log.info('tsc version is', tscVersion); + if (goVersion == '' || nodeVersion == '' || tscVersion == '') { + return false; + } + let traceStreamer = path.normalize(path.join(__dirname, '/bin')); + if (!checkDirExist(traceStreamer + '/trace_streamer_builtin.js')) { + log.error(traceStreamer + '/trace_streamer_builtin.js' + ' Must exist'); + return false; + } + if (!checkDirExist(traceStreamer + '/trace_streamer_builtin.wasm')) { + log.error(traceStreamer + '/trace_streamer_builtin.wasm' + ' Must exist'); + return false; } + return true; } function initLog() { @@ -111,13 +107,8 @@ function initLog() { function main() { log = initLog(); - let argv = process.argv.slice(2)[0]; - if (!argv){ - if (!checkEnvironment()) { - return; - } - } else { - compileServer = false; + if (!checkEnvironment()) { + return; } // clean outDir let outPath = path.normalize(path.join(__dirname, '/', outDir)); @@ -159,29 +150,27 @@ function main() { let thirdDistFile = path.join(__dirname, outDir, value.distFilePath); cpFile(thirdFile, thirdDistFile); }); - if (!argv) { - let traceStreamer = path.normalize(path.join(__dirname, '/bin')); - if (checkDirExist(traceStreamer)) { - let dest = path.normalize(path.join(__dirname, outDir, '/bin')); - copyDirectory(traceStreamer, dest); - // to mv traceStream Wasm and js - cpFile( - traceStreamer + '/trace_streamer_builtin.js', - rootPath + outDir + '/trace/database/trace_streamer_builtin.js' - ); - cpFile( - traceStreamer + '/trace_streamer_builtin.wasm', - rootPath + outDir + '/trace/database/trace_streamer_builtin.wasm' - ); - if (sdkWams.length > 0) { - sdkWams.forEach((fileName) => { - cpFile(traceStreamer + '/' + fileName, rootPath + outDir + '/trace/database/' + fileName); - }); - } - } else { - log.error('traceStreamer dir is not Exits'); - return; + let traceStreamer = path.normalize(path.join(__dirname, '/bin')); + if (checkDirExist(traceStreamer)) { + let dest = path.normalize(path.join(__dirname, outDir, '/bin')); + copyDirectory(traceStreamer, dest); + // to mv traceStream Wasm and js + cpFile( + traceStreamer + '/trace_streamer_builtin.js', + rootPath + outDir + '/trace/database/trace_streamer_builtin.js' + ); + cpFile( + traceStreamer + '/trace_streamer_builtin.wasm', + rootPath + outDir + '/trace/database/trace_streamer_builtin.wasm' + ); + if (sdkWams.length > 0) { + sdkWams.forEach((fileName) => { + cpFile(traceStreamer + '/' + fileName, rootPath + outDir + '/trace/database/' + fileName); + }); } + } else { + log.error('traceStreamer dir is not Exits'); + return; } // compile server if (compileServer) { diff --git a/ide/build.sh b/ide/build.sh deleted file mode 100755 index c406eaeb745eac78a3f4810e1629393655de96a8..0000000000000000000000000000000000000000 --- a/ide/build.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -e -echo "----------------smartperf_ide--------------------" -echo "1=$1" -echo "2=$2" -SOURCE="${BASH_SOURCE[0]}" -cd $(dirname ${SOURCE}) -npm run compile ohos -mv $1/dist $2/dist -mkdir -p $2/dist/bin -mv $2/trace_streamer $2/dist/bin \ No newline at end of file diff --git a/ide/src/base-ui/chart/pagenation/pagination-box.ts b/ide/src/base-ui/chart/pagenation/PaginationBox.ts similarity index 100% rename from ide/src/base-ui/chart/pagenation/pagination-box.ts rename to ide/src/base-ui/chart/pagenation/PaginationBox.ts diff --git a/ide/src/base-ui/checkbox/LitCheckBox.ts b/ide/src/base-ui/checkbox/LitCheckBox.ts index cacb1cdfb46467ef15272ca0c0262aac71c5b5f0..590cb6bdd647b5a1e03923d9ca7abda1cb127577 100644 --- a/ide/src/base-ui/checkbox/LitCheckBox.ts +++ b/ide/src/base-ui/checkbox/LitCheckBox.ts @@ -83,7 +83,6 @@ export class LitCheckBox extends BaseElement { display:flex; justify-content: center; align-items: center; - margin-right:12px; width: 16px; height:16px; border: 1px solid var(--dark-color1,#4D4D4D); diff --git a/ide/src/base-ui/popover/LitPopoverV.ts b/ide/src/base-ui/popover/LitPopoverV.ts index 80e13782ce1fb39cbdc6b00127f7786a1560b7a6..0e3a6a1325ca60662e58f5a74bb32db8f82f55b5 100644 --- a/ide/src/base-ui/popover/LitPopoverV.ts +++ b/ide/src/base-ui/popover/LitPopoverV.ts @@ -33,6 +33,14 @@ export class LitPopover extends BaseElement { } } + set placement(value) { + this.setAttribute('placement',value || 'bottomLeft'); + } + + get placement() { + return this.getAttribute('placement') + } + get trigger() { return this.getAttribute('trigger') || 'hover'; } @@ -80,7 +88,7 @@ export class LitPopover extends BaseElement { border-bottom: 1px solid #f0f0f0; } .content{ - padding: 10px 15px; + padding: 10px; } .trigger-click { position: absolute; diff --git a/ide/src/base-ui/table/lit-table.ts b/ide/src/base-ui/table/lit-table.ts index c2bd2be24c524b82d8859b39b44859c232937baa..4931e6dcc804d315bdf68413e24247975271a4be 100644 --- a/ide/src/base-ui/table/lit-table.ts +++ b/ide/src/base-ui/table/lit-table.ts @@ -29,6 +29,7 @@ export class LitTable extends HTMLElement { currentRecycleList: HTMLDivElement[] = []; currentTreeDivList: HTMLDivElement[] = []; public rememberScrollTop = false; + public getItemTextColor?: (data: any) => string; private ds: Array = []; private recycleDs: Array = []; private normalDs: Array = []; @@ -1445,6 +1446,9 @@ export class LitTable extends HTMLElement { newTableElement.style.position = 'absolute'; newTableElement.style.top = '0px'; newTableElement.style.left = '0px'; + if (this.getItemTextColor) { + newTableElement.style.color = this.getItemTextColor(rowData.data); + } return newTableElement; } @@ -1577,6 +1581,9 @@ export class LitTable extends HTMLElement { } else { this.setMouseIn(false, [element]); } + if (this.getItemTextColor) { + element.style.color = this.getItemTextColor((element as any).data); + } } setSelectedRow(isSelected: boolean, rows: any[]) { diff --git a/ide/src/base-ui/tabs/lit-tabs.ts b/ide/src/base-ui/tabs/lit-tabs.ts index 59c18808dad21ed301921ebb751cdb995e848e92..aa2958fbb806a2e8d0e147b881b02a295ff8bcc3 100644 --- a/ide/src/base-ui/tabs/lit-tabs.ts +++ b/ide/src/base-ui/tabs/lit-tabs.ts @@ -41,7 +41,6 @@ export class LitTabs extends HTMLElement { width:100%; height:100%; flex-shrink:0; - overflow:auto; } .nav-item{ display: inline-flex; diff --git a/ide/src/base-ui/tree/LitTree.ts b/ide/src/base-ui/tree/LitTree.ts new file mode 100644 index 0000000000000000000000000000000000000000..bbd105bd616ed15bc2b89096d095dbd2004fc24e --- /dev/null +++ b/ide/src/base-ui/tree/LitTree.ts @@ -0,0 +1,581 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import './LitTreeNode.js' +import { BaseElement, element } from '../BaseElement.js'; +import { LitTreeNode } from './LitTreeNode.js'; + +export interface TreeItemData { + key: string; + title: string; + icon?: string; //节点的自定义图标 设置show-icon才会生效 + selected?: boolean; //控制是否选择该节点 + checked?: boolean; + children?: Array | null | undefined; +} + +@element('lit-tree') +export class LitTree extends BaseElement { + + private _treeData: Array = []; + private currentSelectedNode: any; + private currentSelectedData: any; + private proxyData: any; + private nodeList: Array = []; + private contextMenu: HTMLDivElement | null | undefined; + private srcDragElement: any; + private dragDirection: string | null | undefined; + + static get observedAttributes() { + return ['show-line', 'show-icon', 'checkable', 'foldable', 'dragable', 'multiple']; //foldable 表示点击目录是否可以折叠 + } + + set treeData(value: Array) { + this._treeData = value; + this.shadowRoot!.querySelector('#root')!.innerHTML = ''; + this.nodeList = []; + this.drawTree(this.shadowRoot!.querySelector('#root'), value, true); + + /*双向绑定*/ + const handler = { + get: (target: any, propkey: any) => { + return target[propkey]; + }, + set: (target: any, propkey: any, value: any, receiver: any) => { + if (target[propkey] !== value) { + if (!value.children) { + value.children = new Proxy([], handler); + } else { + value.children = new Proxy(value.children, handler); + } + target[propkey] = value; + if (!this.currentSelectedNode) { + this._insertNode(null, value); + } else { + if (this.currentSelectedNode.nextElementSibling) { + this._insertNode(this.currentSelectedNode.nextElementSibling, value); + } else { + this.currentSelectedNode.setAttribute('show-arrow', 'true'); + let ul = document.createElement('ul'); + // @ts-ignore + ul.open = 'true' + ul.style.transition = '.3s all'; + this.currentSelectedNode.parentElement.append(ul); + this.currentSelectedNode.arrow = true; + this._insertNode(ul, value); + } + } + } + return true; + } + }; + let setProxy = (v: Array) => { + v.forEach(a => { + if (!a.children) { + a.children = new Proxy([], handler); + } else { + a.children = new Proxy(a.children, handler); + setProxy(a.children || []); + } + }) + }; + setProxy(this._treeData); + this.proxyData = new Proxy(this._treeData, handler); + } + + set multiple(value: boolean) { + if (value) { + this.setAttribute('multiple',''); + } else { + this.removeAttribute('multiple'); + } + } + + get multiple() { + return this.hasAttribute('multiple'); + } + + get treeData() { + return this.proxyData; + } + + set onSelect(fn: any) { + this.addEventListener('onSelect', fn); + } + + set onChange(fn: any) { + this.addEventListener('onChange', fn); + } + + set foldable(value: any) { + if (value) { + this.setAttribute('foldable', ''); + } else { + this.removeAttribute('foldable'); + } + } + + //当 custom element首次被插入文档DOM时,被调用。 + connectedCallback() { + this.onclick = ev => { + this.contextMenu!.style.display = 'none'; + this.currentSelectedData = null; + this.currentSelectedNode = null; + this.selectedNode(null); + } + } + + getCheckdKeys() { + return Array.from(this.shadowRoot!.querySelectorAll('lit-tree-node[checked]')).map((a: any) => a.data.key); + } + + getCheckdNodes() { + return Array.from(this.shadowRoot!.querySelectorAll('lit-tree-node[checked]')).map((a: any) => a.data); + } + + //展开所有节点 + expandKeys(keys: Array) { + keys.forEach(k => this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: any) => b.expand())); + } + + //收起所有节点 + collapseKeys(keys: Array) { + keys.forEach(k => this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: any) => b.collapse())); + } + + checkedKeys(keys: Array) { + keys.forEach(k => this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: any) => { + b.setAttribute('checked', 'true'); + b.checkHandler(); + })); + } + + uncheckedKeys(keys: Array) { + keys.forEach(k => this.shadowRoot!.querySelectorAll(`lit-tree-node[key='${k}']`).forEach((b: any) => { + b.removeAttribute('checked'); + b.removeAttribute('missing'); + b.checkHandler(); + })); + } + + drawTree(parent: any, array: Array, topDepth: boolean = false) { + let that = this; + array.forEach(a => { + let li = document.createElement('li'); + let node: LitTreeNode = document.createElement('lit-tree-node') as LitTreeNode; + node.title = a.title; + node.setAttribute('key', a.key); + node.topDepth = topDepth; + if (this.hasAttribute('dragable')) { + node.draggable = true; + document.ondragover = function (e) { + e.preventDefault(); + }; + //在拖动目标上触发事件 (源元素) + node.ondrag = ev => this.onDrag(ev);//元素正在拖动时触发 + node.ondragstart = ev => this.onDragStart(ev);//用户开始拖动元素时触发 + node.ondragend = ev => this.onDragEnd(ev);// 用户完成元素拖动后触发 + //释放目标时触发的事件: + node.ondragenter = ev => this.onDragEnter(ev);//当被鼠标拖动的对象进入其容器范围内时触发此事件 + node.ondragover = ev => this.onDragOver(ev);//当某被拖动的对象在另一对象容器范围内拖动时触发此事件 + node.ondragleave = ev => this.onDragLeave(ev);//当被鼠标拖动的对象离开其容器范围内时触发此事件 + node.ondrop = ev => this.onDrop(ev);//在一个拖动过程中,释放鼠标键时触发此事件 + } + node.selected = a.selected || false; //是否选中行 + node.checked = a.checked || false;// 是否勾选 + node.data = a; + node.addEventListener('change', (e: any) => { + if (e.detail && !this.multiple) { + this.nodeList.forEach(item => { + item.checked = item.data!.key === node.data!.key; + item.data!.checked = item.checked; + }); + } + var litTreeNodes = this.nodeList.filter(it => it.checked); + if (litTreeNodes.length === 0) { + node.checked = true; + node.data!.checked = true; + } + that.dispatchEvent(new CustomEvent('onChange', {detail: {data: (node as any).data, checked: e.detail}})); + }); + node.multiple = this.hasAttribute('multiple'); + node.checkable = this.getAttribute('checkable') || 'false'; + this.nodeList.push(node); + // @ts-ignore + li.data = a; + li.append(node); + parent.append(li); + let ul = document.createElement('ul'); + // @ts-ignore + ul.open = 'true'; + ul.style.transition = '.3s all'; + if (a.children && a.children.length > 0) { + if (this.hasAttribute('show-icon')) { + if (a.icon) { + (node as any).iconName = a.icon; + } else { + (node as any).iconName = 'folder' + } + } else { + node.iconName = ''; + } + node.arrow = true; + li.append(ul); + this.drawTree(ul, a.children); + } else { + if (this.hasAttribute('show-icon')) { + if (a.icon) { + node.iconName = a.icon; + } else { + node.iconName = 'file'; + } + } else { + node.iconName = ''; + } + node.arrow = false; + } + li.onclick = (e) => { + e.stopPropagation() + if (this.hasAttribute('foldable')) { + // @ts-ignore + if (li.data.children && li.data.children.length > 0) { + node.autoExpand(); + } else { + // @ts-ignore + this.dispatchEvent(new CustomEvent('onSelect', {detail: li.data})) + this.selectedNode(node); + } + } else { + // @ts-ignore + this.dispatchEvent(new CustomEvent('onSelect', {detail: li.data})) + this.selectedNode(node); + } + }; + // node 添加右键菜单功能 + node.oncontextmenu = ev => { + ev.preventDefault(); + this.selectedNode(node); + this.currentSelectedNode = node; + this.currentSelectedData = node.data; + this.contextMenu!.style.display = 'block'; + this.contextMenu!.style.left = ev.pageX + 'px'; + this.contextMenu!.style.top = ev.pageY + 'px'; + }; + }); + this.oncontextmenu = ev => { + ev.preventDefault(); + this.contextMenu!.style.display = 'block'; + this.contextMenu!.style.left = ev.pageX + 'px'; + this.contextMenu!.style.top = ev.pageY + 'px'; + }; + } + + //取消所有节点的选中状态 然后选中当前node节点 + selectedNode(node: LitTreeNode | null | undefined) { + this.shadowRoot!.querySelectorAll('lit-tree-node').forEach((a) => { + a.selected = false; + }) + if (node) { + node.selected = true; + } + } + + closeContextMenu() { + this.contextMenu!.style.display = 'none'; + } + + onDrag(e: MouseEvent) { + + } + + onDragStart(ev: MouseEvent) { + this.srcDragElement = ev.target; + (ev.target! as LitTreeNode).open = 'true'; + (ev.target! as LitTreeNode).autoExpand(); + return undefined; + } + + onDragEnd(ev: MouseEvent) { + this.srcDragElement = null; + return undefined; + } + + onDragEnter(ev: MouseEvent) { + (ev.target as LitTreeNode).style.backgroundColor = '#42b98333'; + return undefined; + } + + onDragOver(ev: MouseEvent) { + let node = ev.target as LitTreeNode; + if (this.srcDragElement.data.key === node.data!.key) return; + let rect = (ev.currentTarget! as any).getBoundingClientRect(); + if (ev.clientX >= rect.left + rect.width / 3 && ev.clientX < rect.left + rect.width) { //bottom-right + this.dragDirection = 'bottom-right'; + node.drawLine('bottom-right'); + } else if (ev.clientY >= rect.top && ev.clientY < rect.top + rect.height / 2) {//上面 + this.dragDirection = 'top'; + node.drawLine('top'); + } else if (ev.clientY <= rect.bottom && ev.clientY > rect.top + rect.height / 2) {//下面 + this.dragDirection = 'bottom'; + node.drawLine('bottom'); + } + return undefined; + } + + onDragLeave(ev: MouseEvent) { + (ev.target as LitTreeNode).style.backgroundColor = '#ffffff00'; + (ev.target as LitTreeNode).drawLine(''); + return undefined; + } + + onDrop(ev: MouseEvent) { + (ev.target as LitTreeNode).style.backgroundColor = '#ffffff00'; + (ev.target as LitTreeNode).drawLine(''); + //移动的不是node节点 而是上层的li节点 + let srcData = this.srcDragElement.data;//获取原节点的data数据 + let dstData = (ev.target as LitTreeNode).data;//获取目标节点的data数据 + if (srcData.key === dstData!.key) return;//同一个节点不用处理 + let srcElement = this.srcDragElement.parentElement; + let srcParentElement = srcElement.parentElement; + let dstElement = (ev.target as LitTreeNode).parentElement; + srcElement.parentElement.removeChild(srcElement);//node li ul 从 ul 中移除 li + if (this.dragDirection === 'top') { + dstElement!.parentElement!.insertBefore(srcElement, dstElement); + } else if (this.dragDirection === 'bottom') { + dstElement!.parentElement!.insertBefore(srcElement, dstElement!.nextSibling); + } else if (this.dragDirection === 'bottom-right') { + let ul = dstElement!.querySelector('ul'); + if (!ul) { + ul = document.createElement('ul'); + ul.style.cssText = 'transition: all 0.3s ease 0s;'; + dstElement!.appendChild(ul); + } + dstElement!.querySelector('lit-tree-node')!.arrow = true;//拖动进入子节点,需要开启箭头 + ul.appendChild(srcElement); + } + let ul1 = dstElement!.querySelector('ul');//如果拖动后目标节点的子节点没有记录,需要关闭arrow箭头 + if (ul1) { + if (ul1.childElementCount == 0) (ul1.previousElementSibling! as LitTreeNode).arrow = false; + } + if (srcParentElement.childElementCount === 0) srcParentElement.previousElementSibling.arrow = false;//如果拖动的原节点的父节点没有子节点需要 关闭arrow箭头 + //拖动调整结构后修改 data树形数据结构 + this.removeDataNode(this._treeData, srcData); + this.addDataNode(this._treeData, srcData, dstData!.key, this.dragDirection!); + this.dispatchEvent(new CustomEvent('drop', { + detail: { + treeData: this._treeData, + srcData: srcData, + dstData: dstData, + type: this.dragDirection + } + })) + ev.stopPropagation(); + return undefined; + } + + //移除treeData中指定的节点 通过key匹配 + removeDataNode(arr: Array, d: TreeItemData) { + let delIndex = arr.findIndex(v => v.key === d.key); + if (delIndex > -1) { + arr.splice(delIndex, 1); + return; + } + for (let i = 0; i < arr.length; i++) { + if (arr[i].children && arr[i].children!.length > 0) { + this.removeDataNode(arr[i].children!, d); + } + } + } + + //中array中匹配到key为k的节点, t='bottom-right' 把d加入到该节点的children中去 t='top' 添加到找到的节点前面 t='bottom' 添加到找到的节点后面 + addDataNode(arr: Array, d: TreeItemData, k: string, t: string) { + for (let i = 0; i < arr.length; i++) { + if (arr[i].key === k) { + if (t === 'bottom-right') { + if (!arr[i].children) arr[i].children = []; + arr[i].children!.push(d); + } else if (t === 'top') { + arr.splice(i, 0, d); + } else if (t === 'bottom') { + arr.splice(i + 1, 0, d); + } + return; + } else { + if (arr[i].children) this.addDataNode(arr[i].children || [], d, k, t); + } + } + } + + insert(obj: TreeItemData) { + if (this.currentSelectedData) { + this.currentSelectedData.children.push(obj); + } else { + this.treeData.push(obj); + } + } + + _insertNode(parent: any, a: any) { + if (!parent) parent = this.shadowRoot!.querySelector('#root'); + let li = document.createElement('li'); + let insertNode = document.createElement('lit-tree-node') as LitTreeNode; + insertNode.title = a.title; + insertNode.setAttribute('key', a.key); + if (this.hasAttribute('dragable')) { + insertNode.draggable = true; + document.ondragover = function (e) { + e.preventDefault(); + } + //在拖动目标上触发事件 (源元素) + insertNode.ondrag = ev => this.onDrag(ev);//元素正在拖动时触发 + insertNode.ondragstart = ev => this.onDragStart(ev);//用户开始拖动元素时触发 + insertNode.ondragend = ev => this.onDragEnd(ev);// 用户完成元素拖动后触发 + //释放目标时触发的事件: + insertNode.ondragenter = ev => this.onDragEnter(ev);//当被鼠标拖动的对象进入其容器范围内时触发此事件 + insertNode.ondragover = ev => this.onDragOver(ev);//当某被拖动的对象在另一对象容器范围内拖动时触发此事件 + insertNode.ondragleave = ev => this.onDragLeave(ev);//当被鼠标拖动的对象离开其容器范围内时触发此事件 + insertNode.ondrop = ev => this.onDrop(ev);//在一个拖动过程中,释放鼠标键时触发此事件 + } + insertNode.selected = a.selected || false; //是否选中行 + insertNode.checked = a.checked || false;// 是否勾选 + insertNode.data = a; + insertNode.addEventListener('change', (e: any) => { + if (e.detail && !this.multiple) { + this.nodeList.forEach(node => { + node.checked = node.data!.key === insertNode.data!.key; + }); + } + this.dispatchEvent(new CustomEvent('onChange', {detail: {data: insertNode.data, checked: e.detail}})); + }) + this.nodeList.push(insertNode); + insertNode.checkable = this.getAttribute('checkable') || 'false'; + insertNode.multiple = this.hasAttribute('multiple'); + // @ts-ignore + li.data = a; + li.append(insertNode); + parent.append(li) + let ul = document.createElement('ul'); + // @ts-ignore + ul.open = 'true' + ul.style.transition = '.3s all'; + if (a.children && a.children.length > 0) { + if (this.hasAttribute('show-icon')) { + if (a.icon) { + insertNode.iconName = a.icon; + } else { + insertNode.iconName = 'folder'; + } + } else { + insertNode.iconName = ''; + } + insertNode.arrow = true; + li.append(ul); + this.drawTree(ul, a.children); + } else { + if (this.hasAttribute('show-icon')) { + if (a.icon) { + insertNode.iconName = a.icon; + } else { + insertNode.iconName = 'file'; + } + } else { + insertNode.iconName = ''; + } + insertNode.arrow = false; + } + li.onclick = (e) => { + e.stopPropagation() + if (this.hasAttribute('foldable')) { + // @ts-ignore + if (li.data.children && li.data.children.length > 0) { + insertNode.autoExpand(); + } else { + // @ts-ignore + this.dispatchEvent(new CustomEvent('onSelect', {detail: li.data})); + this.selectedNode(insertNode); + } + } else { + // @ts-ignore + this.dispatchEvent(new CustomEvent('onSelect', {detail: li.data})); + this.selectedNode(insertNode); + } + } + // node 添加右键菜单功能 + insertNode.oncontextmenu = (ev) => { + ev.preventDefault(); + this.selectedNode(insertNode); + this.currentSelectedNode = insertNode; + this.currentSelectedData = insertNode.data; + this.contextMenu!.style.display = 'block'; + this.contextMenu!.style.left = ev.pageX + 'px'; + this.contextMenu!.style.top = ev.pageY + 'px'; + }; + } + + initElements(): void { + this.contextMenu = this.shadowRoot!.querySelector('#contextMenu'); + } + + initHtml(): string { + return ` + +
    + + `; + } +} + +if (!customElements.get('lit-tree')) { + customElements.define('lit-tree', LitTree); +} \ No newline at end of file diff --git a/ide/src/base-ui/tree/LitTreeNode.ts b/ide/src/base-ui/tree/LitTreeNode.ts new file mode 100644 index 0000000000000000000000000000000000000000..45ee60ff4feae511346f57995c821bb781c3e8ef --- /dev/null +++ b/ide/src/base-ui/tree/LitTreeNode.ts @@ -0,0 +1,486 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import '../icon/LitIcon.js' +import '../checkbox/LitCheckBox.js' +import { BaseElement, element } from '../BaseElement.js'; +import { LitCheckBox } from '../checkbox/LitCheckBox.js'; +import { LitIcon } from '../icon/LitIcon.js'; +import { TreeItemData } from './LitTree.js'; + +@element('lit-tree-node') +export class LitTreeNode extends BaseElement { + + private arrowElement: HTMLSpanElement | null | undefined; + private itemElement: HTMLDivElement | null | undefined; + private checkboxElement: LitCheckBox | null | undefined; + private iconElement: LitIcon | null | undefined; + private _data: TreeItemData | null | undefined; + + static get observedAttributes() { + return ['icon-name', 'icon-size', 'color', 'path', 'title', 'arrow', 'checkable', 'selected', 'checked', 'missing', 'multiple', 'top-depth']; + } + + get checkable() { + return this.getAttribute('checkable') || 'false'; + } + + set data(value: TreeItemData | null | undefined) { + this._data = value; + } + + get data() { + return this._data; + } + + set checkable(value) { + if (value === 'true') { + this.setAttribute('checkable', 'true'); + } else { + this.setAttribute('checkable', 'false'); + } + } + + set multiple(value: boolean) { + if (value) { + this.setAttribute('multiple', ''); + } else { + this.removeAttribute('multiple'); + } + } + + get multiple() { + return this.hasAttribute('multiple'); + } + + + get iconName() { + return this.getAttribute('icon-name') || ''; + } + + set iconName(value) { + this.setAttribute('icon-name', value); + } + + get topDepth() { + return this.hasAttribute('top-depth'); + } + + set topDepth(value) { + if (value) { + this.setAttribute('top-depth', ''); + } else { + this.removeAttribute('top-depth'); + } + } + + get arrow() { + return this.hasAttribute('arrow'); + } + + set arrow(value) { + if (value) { + this.setAttribute('arrow', 'true'); + } else { + this.removeAttribute('arrow'); + } + } + + get open() { + return this.getAttribute('open') || 'true'; + } + + set open(value) { + this.setAttribute('open', value); + } + + get selected() { + return this.hasAttribute('selected'); + } + + set selected(value) { + if (value) { + this.setAttribute('selected', ''); + } else { + this.removeAttribute('selected'); + } + } + + get checked() { + return this.hasAttribute('checked'); + } + + set checked(value) { + if (value === null || !value) { + this.removeAttribute('checked'); + } else { + this.setAttribute('checked', ''); + } + } + + initElements(): void { + this.arrowElement = this.shadowRoot!.querySelector('#arrow'); + this.iconElement = this.shadowRoot!.querySelector('#icon'); + this.itemElement = this.shadowRoot!.querySelector('#item'); + this.checkboxElement = this.shadowRoot!.querySelector('#checkbox'); + this.arrowElement!.onclick = (e) => { + e.stopPropagation(); + this.autoExpand(); + } + this.checkboxElement!.onchange = (e: any) => { + e.stopPropagation(); + this.onChange(e.detail.checked); + return false; + } + //这里需要给checkbox 添加onclick时间 并停止冒泡,不然onchange事件会触发父节点中的 onclick事件 + this.checkboxElement!.onclick = (e) => { + e.stopPropagation(); + }; + this.itemElement!.onclick = (e) => { + e.stopPropagation(); + this.onChange(!this.data?.checked); + }; + } + + onChange(checked: boolean) { + this.checked = checked; + this.data!.checked = checked; + this.checkHandler(); + this.dispatchEvent(new CustomEvent('change', {detail: checked})); + } + + initHtml(): string { + return ` + + +
    + + + ${this.title} +
    + ` + } + + //当 custom element首次被插入文档DOM时,被调用。 + connectedCallback() { + if (this.hasAttribute('checked')) this.checkboxElement!.checked = true; + this.checkHandler(); + } + + checkHandler() { + if (this.checked) { + this.removeAttribute('missing'); + } + if (this.hasAttribute('multiple')) { + if (this.nextElementSibling) { + if (this.checked) { + this.nextElementSibling.querySelectorAll('lit-tree-node').forEach((a: any) => { + a.checked = true; + a.removeAttribute('missing'); + }); + } else { + this.nextElementSibling.querySelectorAll('lit-tree-node').forEach((a: any) => a.checked = false); + } + } + let setCheckStatus = (element: any) => { + if (element.parentElement.parentElement.previousElementSibling && element.parentElement.parentElement.previousElementSibling.tagName === 'LIT-TREE-NODE') { + let allChecked = Array.from(element.parentElement.parentElement.querySelectorAll('lit-tree-node')).every((item: any) => item.checked); + let someChecked = Array.from(element.parentElement.parentElement.querySelectorAll('lit-tree-node')).some((item: any, index, array) => item.checked); + if (allChecked === true) { + element.parentElement.parentElement.previousElementSibling.checked = true; + element.parentElement.parentElement.previousElementSibling.removeAttribute('missing'); + } else if (someChecked) { + element.parentElement.parentElement.previousElementSibling.setAttribute('missing', '') + element.parentElement.parentElement.previousElementSibling.removeAttribute('checked') + } else { + element.parentElement.parentElement.previousElementSibling.removeAttribute('missing') + element.parentElement.parentElement.previousElementSibling.removeAttribute('checked') + } + setCheckStatus(element.parentElement.parentElement.previousElementSibling) + } + } + setCheckStatus(this); + } + } + + expand() { + if (this.open === 'true') return; + let uul = this.parentElement!.querySelector('ul'); + this.expandSection(uul); + this.arrowElement!.style.transform = 'translateX(-50%) rotateZ(0deg)'; + } + + collapse() { + if (this.open === 'false') return; + let uul = this.parentElement!.querySelector('ul'); + this.collapseSection(uul); + this.arrowElement!.style.transform = 'translateX(-50%) rotateZ(-90deg)'; + } + + autoExpand() { + let uul = this.parentElement!.querySelector('ul'); + if (this.open === 'true') { + this.collapseSection(uul); + this.arrowElement!.style.transform = 'translateX(-50%) rotateZ(-90deg)'; + } else { + this.expandSection(uul); + this.arrowElement!.style.transform = 'translateX(-50%) rotateZ(0deg)'; + } + } + + //收起 + collapseSection(element: any) { + if (!element) return; + let sectionHeight = element.scrollHeight; + let elementTransition = element.style.transition; + element.style.transition = ''; + requestAnimationFrame(function () { + element.style.height = sectionHeight + 'px'; + element.style.transition = elementTransition; + requestAnimationFrame(function () { + element.style.height = 0 + 'px'; + }); + }); + this.open = 'false'; + } + + //展开 + expandSection(element: any) { + if (!element) return; + let sectionHeight = element.scrollHeight; + element.style.height = sectionHeight + 'px'; + element.ontransitionend = (e: any) => { + element.ontransitionend = null; + element.style.height = null; + this.open = 'true'; + }; + } + + //当 custom element从文档DOM中删除时,被调用。 + disconnectedCallback() { + + } + + //当 custom element被移动到新的文档时,被调用。 + adoptedCallback() { + + } + + //当 custom element增加、删除、修改自身属性时,被调用。 + attributeChangedCallback(name: string, oldValue: any, newValue: any) { + if (name === 'title') { + this.shadowRoot!.querySelector('#title')!.textContent = newValue; + } else if (name === 'icon-name') { + if (this.iconElement) { + if (newValue !== null && newValue !== '' && newValue !== 'null') { + this.iconElement!.setAttribute('name', newValue); + this.iconElement!.style.display = 'flex'; + } else { + this.iconElement!.style.display = 'none'; + } + } + } else if (name === 'checkable') { + if (this.checkboxElement) { + if (newValue === 'true') { + this.checkboxElement!.style.display = 'inline-block'; + } else { + this.checkboxElement!.style.display = 'none'; + } + } + } else if (name === 'checked') { + if (this.checkboxElement) { + this.checkboxElement.checked = this.hasAttribute('checked'); + } + } + } + + //在node top top-right bottom bottom-right 画线条 + drawLine(direction: string/*string[top|bottom|top-right|bottom-right]*/) { + let item = this.shadowRoot!.querySelector('#item'); + if (!item) return; + item.removeAttribute('line-top'); + item.removeAttribute('line-top-right'); + item.removeAttribute('line-bottom'); + item.removeAttribute('line-bottom-right'); + switch (direction) { + case 'top': + item.setAttribute('line-top', '') + break; + case 'bottom': + item.setAttribute('line-bottom', '') + break; + case 'top-right': + item.setAttribute('line-top-right', '') + break; + case 'bottom-right': + item.setAttribute('line-bottom-right', '') + break; + } + } +} + +if (!customElements.get('lit-tree-node')) { + customElements.define('lit-tree-node', LitTreeNode); +} \ No newline at end of file diff --git a/ide/src/trace/SpApplication.ts b/ide/src/trace/SpApplication.ts index b79fd52eec0aa7cdcb288f819c86b46203d476ea..02ad225ba96917337161bcf4b4f99d81bd23de62 100644 --- a/ide/src/trace/SpApplication.ts +++ b/ide/src/trace/SpApplication.ts @@ -49,7 +49,7 @@ import './component/trace/base/TraceRowConfig.js'; import { TraceRowConfig } from './component/trace/base/TraceRowConfig.js'; import { ColorUtils } from './component/trace/base/ColorUtils.js'; import { SpStatisticsHttpUtil } from '../statistics/util/SpStatisticsHttpUtil.js'; -import { SpFlags } from './component/SpFlags.js'; +import { FlagsConfig, SpFlags } from './component/SpFlags.js'; import './component/SpFlags.js'; @element('sp-application') @@ -331,16 +331,18 @@ export class SpApplication extends BaseElement { color: var(--dark-color1,#47A7E0); } .chart-filter { - display: block; visibility: hidden; z-index: -1; } :host([chart_filter]) .chart-filter { + display: grid; + grid-template-rows: min-content min-content min-content max-content auto; + overflow-y: clip; + height: 99%; visibility: visible; position: absolute; width: 40%; - height: 100%; right: 0; z-index: 1001; top: 0; @@ -388,7 +390,7 @@ export class SpApplication extends BaseElement { - + `; @@ -598,8 +600,10 @@ export class SpApplication extends BaseElement { menu!.style.pointerEvents = 'none'; sidebarButton!.style.pointerEvents = 'none'; that.search = litSearch.isLoading; - litSearch.style.display = 'none'; - litRecordSearch.style.display = 'block'; + if (!that.search) { + litSearch.style.display = 'none'; + litRecordSearch.style.display = 'block'; + } window.publish(window.SmartEvent.UI.KeyboardEnable, { enable: false, }); @@ -731,8 +735,8 @@ export class SpApplication extends BaseElement { }); } } - if ((window as any).cpuCount === 0) { - //if cpu count > 1 then show Scheduling-Analysis menu else hide it + if ((window as any).cpuCount === 0 || !FlagsConfig.getFlagsConfigEnableStatus('SchedulingAnalysis')) { + //if cpu count > 1 or SchedulingAnalysis config 'enable' then show Scheduling-Analysis menu else hide it menus.splice(1, 1); } return menus; @@ -924,6 +928,9 @@ export class SpApplication extends BaseElement { spSystemTrace!.reset((command: string, percent: number) => { setProgress(command); }); + window.publish(window.SmartEvent.UI.MouseEventEnable, { + mouseEnable: false, + }); window.clearTraceRowComplete(); that.freshMenuDisable(true); SpSchedulingAnalysis.resetCpu(); diff --git a/ide/src/trace/bean/AbilityMonitor.ts b/ide/src/trace/bean/AbilityMonitor.ts index 34cc931dcd405a6b66c267299b4e550948d038b7..9a638dfadc530102d9b1b742684e1d768db0c248 100644 --- a/ide/src/trace/bean/AbilityMonitor.ts +++ b/ide/src/trace/bean/AbilityMonitor.ts @@ -130,3 +130,51 @@ export class SystemMemorySummary { cmaFree: string = '0'; zram: string = '0'; } + +export class Dma { + processId: number = -1; + timeStamp: string = ''; + startNs: number = -1; + expTaskComm: string| number = ''; + avgSize: number = -1; + minSize: number = -1; + maxSize: number = -1; + bufName: string | number = ''; + expName: string | number = ''; + size: number = -1; + processName: string = ''; + process: string = ''; //processName + processId + fd: number = -1; + ino: number = -1; + expPid: number = -1; + flag: number = -1; + avgSizes: string = ''; + minSizes: string = ''; + maxSizes: string = ''; + sizes: string = ''; + sumSize: number = -1; + sumSizes: string = ''; +} + +export class GpuMemory { + processId: number = -1; + threadId: number = -1; + timeStamp: string = ''; + expTaskComm: string = ''; + startNs: number = -1; + avgSize: number = -1; + minSize: number = -1; + maxSize: number = -1; + gpuName: string = ''; + processName: string = ''; + process: string = ''; //processName + processId + threadName: string = ''; + thread: string = ''; //threadName + threadI + size: number = -1; + avgSizes: string = ''; + minSizes: string = ''; + maxSizes: string = ''; + sizes: string = ''; + sumSize: number = -1; + sumSizes: string = ''; +} diff --git a/ide/src/trace/bean/BoxSelection.ts b/ide/src/trace/bean/BoxSelection.ts index 8186a2e071fd147d850aab04046a93b8b6c6d47d..530ff16f21abbf05095e758e0b8046c4376766ed 100644 --- a/ide/src/trace/bean/BoxSelection.ts +++ b/ide/src/trace/bean/BoxSelection.ts @@ -72,6 +72,7 @@ export class SelectionParam { powerEnergy: Array = []; anomalyEnergy: Array = []; smapsType: Array = []; + vmtrackershm: Array = []; promiseList: Array> = []; jankFramesData: Array = []; jsMemory: Array = []; @@ -80,6 +81,25 @@ export class SelectionParam { frameAnimation: Array = []; frameSpacing: Array = []; jsCpuProfilerData: Array = []; + gpu: { + gl:boolean, + gpuTotal: boolean, + gpuWindow: boolean + } = { + gl: false, + gpuWindow:false, + gpuTotal: false + } + purgeableTotalAbility: Array = []; + purgeableTotalVM: Array = []; + purgeablePinAbility: Array = []; + purgeablePinVM: Array = []; + purgeableTotalSelection: Array = []; + purgeablePinSelection: Array = []; + dmaAbilityData: Array = []; + gpuMemoryAbilityData: Array = []; + dmaVmTrackerData: Array = []; + gpuMemoryTrackerData: Array = []; } export class BoxJumpParam { diff --git a/ide/src/trace/bean/MemoryConfig.ts b/ide/src/trace/bean/MemoryConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..014b1f038bd1e51a80a2a3ef7339d71a09fccd1c --- /dev/null +++ b/ide/src/trace/bean/MemoryConfig.ts @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export class MemoryConfig { + private static instance: MemoryConfig; + pid: number = 0; + iPid: number = 0; + processName: string = ''; + interval: number = 0; + snapshotDur: number = 0; + + public static getInstance(): MemoryConfig { + if (!this.instance) { + this.instance = new MemoryConfig(); + } + return this.instance; + } + + public updateConfig(pid: number, iPid: number, processName: string, interval: number): void { + this.pid = pid; + this.iPid = iPid; + this.processName = processName; + this.interval = interval; + this.snapshotDur = (interval * 1000 * 1000) / 5 + } +} diff --git a/ide/src/trace/bean/SmapsStruct.ts b/ide/src/trace/bean/SmapsStruct.ts index 44862efd90cd58ff7e465cf02a1a82e10f3d80d6..17070f7a4bbb96bc040b7ddaa547ee8e6dc0b4a3 100644 --- a/ide/src/trace/bean/SmapsStruct.ts +++ b/ide/src/trace/bean/SmapsStruct.ts @@ -1,3 +1,4 @@ + /* * Copyright (C) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - export class Smaps { tsNS: number = -1; start_addr: string = ''; @@ -25,31 +25,37 @@ export class Smaps { reside: number = 0; dirty: number = 0; swapper: number = 0; - address: string = ''; - type: string = ''; + type: SmapsType = 0; + typeName: string = ''; dirtyStr: string = ''; swapperStr: string = ''; rssStr: string = ''; pssStr: string = ''; sizeStr: string = ''; resideStr: string = ''; + shared_clean : number = 0; + shared_dirty:number = 0; + private_clean:number = 0; + private_dirty:number = 0; + swap:number = 0; + swap_pss:number = 0; + count:number = 0; } - export class SmapsTreeObj { constructor(id: string, pid: string, type: string) { this.id = id; this.pid = pid; - this.type = type; + this.typeName = type; } id: string = ''; pid: string = ''; rsspro: number = 0; rssproStr: string = ''; - type: string = ''; + typeName: string = ''; reg: number = 0; regStr: string = ''; - path: string = ''; + path: any = ''; rss: number = 0; rssStr: string = ''; dirty: number = 0; @@ -62,5 +68,35 @@ export class SmapsTreeObj { sizeStr: string = ''; respro: number = 0; resproStr: string = ''; + sizePro:number = 0; + sizeProStr :string = ''; + count :number = 0 ; + sharedClean : number = 0; + sharedCleanStr:string = ''; + sharedDirty:number = 0; + sharedDirtyStr:string = ''; + privateClean:number = 0; + privateCleanStr:string = ''; + privateDirty:number = 0; + privateDirtyStr:string = ''; + swap:number = 0; + swapStr:string = ''; + swapPss:number = 0; + swapPssStr:string = ''; children: Array = []; } +export enum SmapsType{ + TYPE_CODE_SYS, + TYPE_CODE_APP, + TYPE_DATA_SYS, + TYPE_DATA_APP, + TYPE_UNKNOWN_ANON, + TYPE_STACK, + TYPE_JS_HEAP, + TYPE_JAVA_VM, + TYPE_NATIVE_HEAP, + TYPE_ASHMEM, + TYPE_OTHER_SYS, + TYPE_OTHER_APP +} +export const TYPE_STRING = ['CODE_SYS','CODE_APP','DATA_SYS','DATA_APP','UNKNOWN_ANON','STACK','JS_HEAP','JAVA_VM','NATIVE_HEAP','ASHMEM','OTHER_SYS','OTHER_APP'] \ No newline at end of file diff --git a/ide/src/trace/component/SpFlags.ts b/ide/src/trace/component/SpFlags.ts index 8c0fcfac7ee5dc3225419e627e1f16733ee0cffc..d1c94b495ed642b3c2657e00729a0555fd0ab270 100644 --- a/ide/src/trace/component/SpFlags.ts +++ b/ide/src/trace/component/SpFlags.ts @@ -244,6 +244,11 @@ export class FlagsConfig { switchOptions: [{ option: 'Enabled' }, { option: 'Disabled', selected: true }], describeContent: 'App Startup templates', }, + { + title: 'SchedulingAnalysis', + switchOptions: [{ option: 'Enabled' }, { option: 'Disabled', selected: true }], + describeContent: 'Scheduling analysis templates', + }, ]; static getAllFlagConfig(): Array { @@ -332,6 +337,15 @@ export class FlagsConfig { } } + static getFlagsConfigEnableStatus(flagName: string): boolean { + let config = FlagsConfig.getFlagsConfig(flagName); + let enable: boolean = false; + if (config && config[flagName]) { + enable = config[flagName] === 'Enabled'; + } + return enable; + } + static updateFlagsConfig(key: string, value: unknown): void { let flagsConfigStr = window.localStorage.getItem(FlagsConfig.FLAGS_CONFIG_KEY); let flagConfigObj: Params = {}; diff --git a/ide/src/trace/component/SpInfoAndStas.ts b/ide/src/trace/component/SpInfoAndStas.ts index 9b919242a26adb5d443a3dffd59f3d66fc7c76e1..b2be3ccb7673fe026f74cefb8b601b9a9b3af240 100644 --- a/ide/src/trace/component/SpInfoAndStas.ts +++ b/ide/src/trace/component/SpInfoAndStas.ts @@ -26,42 +26,24 @@ export class SpInfoAndStats extends BaseElement { private infoData: Array = []; private metaTableEl: LitTable | undefined; private infoTableEl: LitTable | undefined; - private th: HTMLElement | undefined; - private progressLoad: LitProgressBar | undefined; - - static get observedAttributes() { - return []; - } initElements(): void { - this.progressLoad = this.shadowRoot?.querySelector('.load-metric') as LitProgressBar; this.metaTableEl = this.shadowRoot!.querySelector('#metaData-table') as LitTable; this.infoTableEl = this.shadowRoot!.querySelector('#stats-table') as LitTable; - - this.infoTableEl.style.overflow = 'visible'; - this.metaTableEl.style.overflow = 'visible'; - this.infoTableEl.style.width = 'auto'; - this.metaTableEl.style.width = 'auto'; - this.th = this.shadowRoot!.querySelector('.th') as HTMLElement; } - initInfoAndStatsData() { - this.progressLoad!.loading = true; + initInfoAndStatsData(): void { + let progressLoad = this.shadowRoot?.querySelector('.load-metric') as LitProgressBar; + progressLoad!.loading = true; let time = new Date().getTime(); this.initMetricItemData().then(() => { let durTime = new Date().getTime() - time; - info('InfoAndStatsData query time is: ' + durTime + 'ms'); + info(`InfoAndStatsData query time is: ${durTime}ms`); if (this.metaData.length > 0) { this.metaTableEl!.recycleDataSource = this.metaData; } else { this.metaTableEl!.recycleDataSource = []; } - new ResizeObserver(() => { - if (this.parentElement?.clientHeight != 0) { - this.metaTableEl!.style.height = '100%'; - this.metaTableEl!.reMeauseHeight(); - } - }).observe(this.parentElement!); info('metaData(metric) size is: ', this.metaData.length); if (this.infoData.length > 0) { this.infoTableEl!.recycleDataSource = this.infoData; @@ -69,32 +51,29 @@ export class SpInfoAndStats extends BaseElement { this.infoTableEl!.recycleDataSource = []; } new ResizeObserver(() => { - if (this.parentElement?.clientHeight != 0) { + if (this.parentElement?.clientHeight !== 0) { + this.metaTableEl!.style.height = '100%'; + this.metaTableEl!.reMeauseHeight(); this.infoTableEl!.reMeauseHeight(); } }).observe(this.parentElement!); info('infoData(metric) size is: ', this.infoData.length); - let metaDataStyle: HTMLDivElement | undefined | null = this.shadowRoot - ?.querySelector('#metaData-table') - ?.shadowRoot?.querySelector('div.body') as HTMLDivElement; - let metaDataHeadStyle: HTMLDivElement | undefined | null = this.shadowRoot - ?.querySelector('#metaData-table') - ?.shadowRoot?.querySelector('div.thead') as HTMLDivElement; - let statsStyle: HTMLDivElement | undefined | null = this.shadowRoot - ?.querySelector('#stats-table') - ?.shadowRoot?.querySelector('div.body') as HTMLDivElement; - let statsHeadStyle: HTMLDivElement | undefined | null = this.shadowRoot - ?.querySelector('#stats-table') - ?.shadowRoot?.querySelector('div.thead') as HTMLDivElement; - + let metaDataStyle: HTMLDivElement | undefined | null = this.metaTableEl!.shadowRoot?. + querySelector('div.body') as HTMLDivElement; + let metaDataHeadStyle: HTMLDivElement | undefined | null = this.metaTableEl!.shadowRoot?. + querySelector('div.thead') as HTMLDivElement; + let statsStyle: HTMLDivElement | undefined | null = this.infoTableEl!.shadowRoot?. + querySelector('div.body') as HTMLDivElement; + let statsHeadStyle: HTMLDivElement | undefined | null = this.infoTableEl!.shadowRoot?. + querySelector('div.thead') as HTMLDivElement; + let timeOutTs = 20; setTimeout(() => { this.initDataTableStyle(metaDataStyle!); this.initDataTableStyle(metaDataHeadStyle!); this.initDataTableStyle(statsStyle!); this.initDataTableStyle(statsHeadStyle!); - }, 20); - - this.progressLoad!.loading = false; + }, timeOutTs); + progressLoad!.loading = false; }); } @@ -111,7 +90,7 @@ export class SpInfoAndStats extends BaseElement { this.infoTableEl!.style.borderRadius = '16'; } - async initMetricItemData() { + async initMetricItemData(): Promise { this.metaData = []; this.infoData = []; let mete = await queryTraceMetaData(); @@ -127,110 +106,106 @@ export class SpInfoAndStats extends BaseElement { if (info) { for (let index = 0; index < info.length; index++) { this.infoData.push({ - event_name: info[index].event_name, - stat_type: info[index].stat_type, + eventName: info[index].event_name, + statType: info[index].stat_type, count: info[index].count, }); } } } - connectedCallback() {} - - disconnectedCallback() {} - - attributeChangedCallback(name: string, oldValue: string, newValue: string) {} - initHtml(): string { return ` -