WorkDir.vue 11.5 KB
Newer Older
H
Hao Sun 已提交
1
<template>
aaronchen2k2k's avatar
aaronchen2k2k 已提交
2
  <div class="workdir">
Z
zhaoke 已提交
3 4 5 6 7 8 9 10 11
    <Tree 
    :data="treeData" 
    :checkable="checkable"
    ref="treeRef" 
    @active="selectNode" 
    @check="checkNode"
    @clickToolbar="onToolbarClicked" 
    @collapse="expandNode" 
    :defaultCollapsedMap="collapsedMap"
Z
zhaoke 已提交
12
    :defaultCollapsed="true"
Z
zhaoke 已提交
13
    />
14
    <FormNode :show="showModal" @submit="createNode" @cancel="modalClose" ref="formNode" />
aaronchen2k2k's avatar
aaronchen2k2k 已提交
15
  </div>
H
Hao Sun 已提交
16
</template>
aaronchen2k2k's avatar
aaronchen2k2k 已提交
17 18

<script setup lang="ts">
19 20
import { useI18n } from "vue-i18n";
import { useStore } from "vuex";
aaronchen2k2k's avatar
aaronchen2k2k 已提交
21
import { StateType as GlobalData } from "@/store/global";
22 23 24
import { ZentaoData } from "@/store/zentao";
import { ScriptData } from "@/views/script/store";
import { WorkspaceData } from "@/store/workspace";
aaronchen2k2k's avatar
aaronchen2k2k 已提交
25 26
import { resizeWidth } from "@/utils/dom";
import Tree from "@/components/Tree.vue";
R
root 已提交
27
import notification from "@/utils/notification";
Z
zhaoke 已提交
28
import { computed, defineExpose, onMounted, onUnmounted, ref, watch } from "vue";
Z
zhaoke 已提交
29 30 31

import bus from "@/utils/eventBus";
import {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
32 33 34 35
  getExpandedKeys,
  getScriptDisplayBy,
  getScriptFilters,
  setExpandedKeys,
Z
zhaoke 已提交
36 37
} from "@/utils/cache";
import {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
38 39 40
  getCaseIdsFromReport,
  getNodeMap,
  listFilterItems,
Z
zhaoke 已提交
41
} from "@/views/script/service";
42 43
import { useRouter } from "vue-router";
import { isWindows } from "@/utils/comm";
Z
zhaoke 已提交
44 45
import debounce from "lodash.debounce";
import throttle from "lodash.debounce";
Z
zhaoke 已提交
46
import Modal from "@/utils/modal"
Z
zhaoke 已提交
47
import FormNode from "./FormNode.vue";
Z
zhaoke 已提交
48
import { key } from "localforage";
Z
zhaoke 已提交
49
import settings from "@/config/settings";
Z
zhaoke 已提交
50

51
const { t } = useI18n();
aaronchen2k2k's avatar
aaronchen2k2k 已提交
52

aaronchen2k2k's avatar
aaronchen2k2k 已提交
53 54
const store = useStore<{ global: GlobalData, Zentao: ZentaoData, Script: ScriptData, Workspace: WorkspaceData }>();
const global = computed<any>(() => store.state.global.tabIdToWorkspaceIdMap);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
55 56
const currSite = computed<any>(() => store.state.Zentao.currSite);
const currProduct = computed<any>(() => store.state.Zentao.currProduct);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
57

aaronchen2k2k's avatar
aaronchen2k2k 已提交
58
const currWorkspace = computed<any>(() => store.state.Script.currWorkspace);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
59

Z
zhaoke 已提交
60 61
const isWin = isWindows()

aaronchen2k2k's avatar
aaronchen2k2k 已提交
62 63
store.dispatch('Zentao/fetchLangs')
const langs = computed<any[]>(() => store.state.Zentao.langs);
Z
zhaoke 已提交
64

Z
zhaoke 已提交
65 66 67 68 69 70 71 72 73 74
const router = useRouter();
let workspace = router.currentRoute.value.params.workspace as string
workspace = workspace === '-' ? '' : workspace
let seq = router.currentRoute.value.params.seq as string
seq = seq === '-' ? '' : seq
let scope = router.currentRoute.value.params.scope as string
scope = scope === '-' ? '' : scope

const filerType = ref('')
const filerValue = ref('')
Z
zhaoke 已提交
75
const showModal = ref(false)
76
const toolbarAction = ref('')
aaronchen2k2k's avatar
aaronchen2k2k 已提交
77
const currentNode = ref({} as any) // parent node for create node
Z
zhaoke 已提交
78
const collapsedMap = ref({} as any)
Z
zhaoke 已提交
79

aaronchen2k2k's avatar
aaronchen2k2k 已提交
80
onMounted(() => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
81 82 83 84 85
  console.log('onMounted')
  initData();
  setTimeout(() => {
    resizeWidth('main', 'left', 'splitter-h', 'right', 380, 800)
  }, 600)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
86 87
})

aaronchen2k2k's avatar
aaronchen2k2k 已提交
88
const onToolbarClicked = (e) => {
Z
zhaoke 已提交
89
  const node = e.node == undefined ? treeDataMap.value[''] : treeDataMap.value[e.node.id]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
90
  store.dispatch('Script/changeWorkspace',
91
    { id: node.workspaceId, type: node.workspaceType })
aaronchen2k2k's avatar
aaronchen2k2k 已提交
92

aaronchen2k2k's avatar
aaronchen2k2k 已提交
93
  currentNode.value = node;
Z
zhaoke 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
  switch (e.event.key) {
    case 'runTest':
      runTest(currentNode);
      break;
    case 'createFile':
    case 'createWorkspace':
    case 'createDir':
      showModal.value = true;
      toolbarAction.value = e.event.key;
      break;
    case 'deleteWorkspace':
      Modal.confirm({
          title: t('delete'),
          content: t('confirm_to_delete_workspace', { p: node.title }),
          showOkBtn: true
        },
        {
          "onOk": () => {
            store.dispatch('Workspace/removeWorkspace', node.path)
              .then((response) => {
114 115 116 117 118
              if (response) {
                notification.success({ message: t('delete_success') });
                loadScripts()
              }
            })
Z
zhaoke 已提交
119
          }
120
        }
Z
zhaoke 已提交
121 122 123 124 125 126 127 128 129 130 131 132 133
      );
    break;
    case 'runScript':
      console.log('run script', currentNode.value);
      bus.emit(settings.eventExec,
        {execType: currentNode.value.workspaceType === 'ztf' ? 'ztf' : 'unit', scripts: currentNode.value.isLeaf ? [currentNode.value] : currentNode.value.children});
      break;
    case 'checkinCase':
      console.log('checkin case', currentNode.value);
      break;
    case 'checkoutCase':
      console.log('checkout case', currentNode.value);
      break;
aaronchen2k2k's avatar
aaronchen2k2k 已提交
134
  }
Z
zhaoke 已提交
135 136 137
}

const runTest = (node) => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
138 139 140 141 142 143 144 145 146 147 148 149
  console.log('runTest', node.value)

  store.dispatch('tabs/open', {
    id: 'workspace-' + node.value.workspaceId,
    title: node.value.title,
    type: 'execUnit',
    changed: false,
    data: {
      workspaceId: node.value.workspaceId,
      workspaceType: node.value.workspaceType,
    }
  });
Z
zhaoke 已提交
150
}
Z
zhaoke 已提交
151

Z
zhaoke 已提交
152
const modalClose = () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
153
  showModal.value = false;
Z
zhaoke 已提交
154 155 156 157
}

const treeRef = ref<{ isAllCollapsed: () => boolean, toggleAllCollapsed: () => void }>();

aaronchen2k2k's avatar
aaronchen2k2k 已提交
158
let treeData = computed<any>(() => store.state.Script.list);
H
Hao Sun 已提交
159 160 161 162

const checkable = ref(false);

function toggleCheckable(toggle?: boolean) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
163 164 165 166
  if (toggle === undefined) {
    toggle = !checkable.value;
  }
  checkable.value = toggle;
H
Hao Sun 已提交
167 168
}

Z
zhaoke 已提交
169 170

const selectCasesFromReport = async (): Promise<void> => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
171
  if (!seq) return
Z
zhaoke 已提交
172

aaronchen2k2k's avatar
aaronchen2k2k 已提交
173 174 175 176
  getCaseIdsFromReport(workspace, seq, scope).then((json) => {
    checkedKeys.value = json.data
    router.push(`/script/index`) // remove the params of re-test
  })
Z
zhaoke 已提交
177 178 179 180
}
selectCasesFromReport()

watch(currProduct, () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
181 182
  console.log('watch currProduct', currProduct.value.id)
  initData()
183
}, { deep: true })
Z
zhaoke 已提交
184 185

watch(treeData, (currConfig) => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
186 187
  console.log('watch treeData', treeData.value)
  onTreeDataChanged()
188
}, { deep: true })
Z
zhaoke 已提交
189 190 191 192

let filerItems = ref([] as any)

const loadScripts = async () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
193 194
  console.log(`loadScripts should be executed only once`)
  console.log(`filerType: ${filerType.value}, filerValue: ${filerValue.value}`)
Z
zhaoke 已提交
195

196
  const params = { displayBy: displayBy.value, filerType: filerType.value, filerValue: filerValue.value } as any
aaronchen2k2k's avatar
aaronchen2k2k 已提交
197
  store.dispatch('Script/listScript', params)
Z
zhaoke 已提交
198 199 200
}

const onTreeDataChanged = async () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
201
  getNodeMapCall()
Z
zhaoke 已提交
202

aaronchen2k2k's avatar
aaronchen2k2k 已提交
203 204
  getExpandedKeys(currSite.value.id, currProduct.value.id).then(async cachedKeys => {
    console.log('cachedKeys', currSite.value.id, currProduct.value.id)
Z
zhaoke 已提交
205

aaronchen2k2k's avatar
aaronchen2k2k 已提交
206
    if (cachedKeys) expandedKeys.value = cachedKeys
Z
zhaoke 已提交
207

aaronchen2k2k's avatar
aaronchen2k2k 已提交
208
    if (!cachedKeys || cachedKeys.length === 0) {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
209
      // 修改
210 211
      // getOpenKeys(treeData.value[0], false) // expend first level folder
      // await setExpandedKeys(currSite.value.id, currProduct.value.id, expandedKeys.value)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
212 213
    }
  })
Z
zhaoke 已提交
214 215 216 217
}

// display
const loadDisplayBy = async () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
218
  displayBy.value = await getScriptDisplayBy(currSite.value.id, currProduct.value.id)
Z
zhaoke 已提交
219 220 221 222
}

// filters
const loadFilterItems = async () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
  const data = await getScriptFilters(displayBy.value, currSite.value.id, currProduct.value.id)

  if (!filerType.value) {
    filerType.value = data.by
  }
  filerValue.value = data.val

  if (!currProduct.value.id && filerType.value !== 'workspace') {
    filerType.value = 'workspace'
    filerValue.value = ''
  }

  if (filerType.value) {
    const result = await listFilterItems(filerType.value)
    filerItems.value = result.data

    let found = false
    if (filerItems.value) {
      filerItems.value.forEach((item) => {
        // console.log(`${filerValue.value}, ${item.value}`)
        if (filerValue.value === item.value) found = true
      })
Z
zhaoke 已提交
245 246
    }

aaronchen2k2k's avatar
aaronchen2k2k 已提交
247 248
    if (!found) filerValue.value = ''
  }
Z
zhaoke 已提交
249 250 251
}

const initData = debounce(async () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
252 253
  console.log('init')
  if (!currSite.value.id) return
Z
zhaoke 已提交
254

aaronchen2k2k's avatar
aaronchen2k2k 已提交
255 256 257
  await loadDisplayBy()
  await loadFilterItems()
  await loadScripts()
Z
zhaoke 已提交
258 259 260 261 262 263 264
}, 50)

// only do it when switch from another pages, otherwise will called by watching currProduct method.
if (filerValue.value.length === 0) initData()

const expandedKeys = ref<string[]>([]);
const getOpenKeys = (treeNode: any, openAll: boolean) => { // expand top one level if openAll is false
aaronchen2k2k's avatar
aaronchen2k2k 已提交
265 266
  if (!treeNode) return
  expandedKeys.value.push(treeNode.path)
Z
zhaoke 已提交
267

aaronchen2k2k's avatar
aaronchen2k2k 已提交
268 269 270 271 272
  if (treeNode.children && openAll) {
    treeNode.children.forEach((item, index) => {
      getOpenKeys(item, openAll)
    })
  }
Z
zhaoke 已提交
273

aaronchen2k2k's avatar
aaronchen2k2k 已提交
274
  console.log('keys', expandedKeys.value)
Z
zhaoke 已提交
275 276
}

Z
zhaoke 已提交
277 278 279 280 281 282 283
watch(expandedKeys, () => {
    console.log('watch expandedKeys')
    for (let treeDataKey in treeDataMap.value) {
        collapsedMap.value[treeDataKey] = expandedKeys.value.indexOf(treeDataKey) !== -1 ? false : true
    }
}, { deep: true })

Z
zhaoke 已提交
284 285 286 287 288 289 290 291 292 293
const selectedKeys = ref<string[]>([])
const checkedKeys = ref<string[]>([])

let isExpand = ref(false);
let showCheckbox = ref(false)
let displayBy = ref('workspace')

let tree = ref(null)

onMounted(() => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
294
  console.log('onMounted', tree)
Z
zhaoke 已提交
295 296
})
onUnmounted(() => {
297
  console.log('onUnmounted', tree)
Z
zhaoke 已提交
298 299 300
})

const selectNode = (activeNode) => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
301
  console.log('selectNode', activeNode.activeID, global.value)
Z
zhaoke 已提交
302

Z
zhaoke 已提交
303
  const node = treeDataMap.value[activeNode.activeID]
aaronchen2k2k's avatar
aaronchen2k2k 已提交
304
  if (node.workspaceType !== 'ztf') checkNothing()
Z
zhaoke 已提交
305

aaronchen2k2k's avatar
aaronchen2k2k 已提交
306
  store.dispatch('Script/getScript', node)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
307
  if (node.type === 'file') {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
308 309
    const tabId = node.workspaceType === 'ztf' && node.path.indexOf('.exp') !== node.path.length - 4
        ? 'script-' + node.path : 'code-' + node.path
aaronchen2k2k's avatar
aaronchen2k2k 已提交
310 311
    global.value[tabId] = node.workspaceId

aaronchen2k2k's avatar
aaronchen2k2k 已提交
312
    store.dispatch('tabs/open', {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
313
      id: tabId,
aaronchen2k2k's avatar
aaronchen2k2k 已提交
314 315 316 317 318 319 320
      title: node.title,
      changed: false,
      type: 'script',
      data: node.path
    });
  }

aaronchen2k2k's avatar
aaronchen2k2k 已提交
321
  store.dispatch('Script/changeWorkspace',
322
    { id: node.workspaceId, type: node.workspaceType })
Z
zhaoke 已提交
323 324
}

R
root 已提交
325 326
const checkNode = (checkedKeys) => {
  console.log('checkNode', checkedKeys.checked)
Z
zhaoke 已提交
327
  store.dispatch('Script/setCheckedNodes', checkedKeys.checked)
328 329
  //   scriptStore.dispatch('Script/changeWorkspace',
  //       {id: e.node.dataRef.workspaceId, type: e.node.dataRef.workspaceType})
Z
zhaoke 已提交
330 331 332
}

const checkNothing = () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
333
  checkedKeys.value = []
Z
zhaoke 已提交
334 335 336 337 338 339 340
}

let contextNode = ref({} as any)
let menuStyle = ref({} as any)
const editedData = ref<any>({})
const nameFormVisible = ref(false)

Z
zhaoke 已提交
341
const treeDataMap = computed<any>(() => store.state.Script.treeDataMap);
Z
zhaoke 已提交
342
const getNodeMapCall = throttle(async () => {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
343
  treeData.value.forEach(item => {
Z
zhaoke 已提交
344
    getNodeMap(item, treeDataMap.value)
aaronchen2k2k's avatar
aaronchen2k2k 已提交
345
  })
Z
zhaoke 已提交
346 347 348 349 350
}, 300)

let rightClickedNode = {} as any
let createAct = ''

Z
zhaoke 已提交
351
const formNode = ref({} as any)
Z
zhaoke 已提交
352
const createNode = (formData) => {
353 354
  const mode = 'child';
  let type = 'dir';
355
  if(toolbarAction.value === 'createFile') type = 'node'
aaronchen2k2k's avatar
aaronchen2k2k 已提交
356
  store.dispatch('Script/createScript', {
357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374
    name: formData.name, mode: mode, type: type, target: currentNode.value.path,
    workspaceId: currentNode.value.workspaceId, productId: currProduct.value.id,
  }).then((result) => {
    if (result) {
      formNode.value.clearFormData()
      showModal.value = false;
      notification.success({ message: t('create_success') });
      nameFormVisible.value = false

      if (mode == 'child') {
        expandedKeys.value.push(rightClickedNode.path)
      }
      if (type === 'dir') {
        expandedKeys.value.push(result)
      }
      setExpandedKeys(currSite.value.id, currProduct.value.id, expandedKeys.value)
    } else {
      notification.error({ message: t('create_fail') });
aaronchen2k2k's avatar
aaronchen2k2k 已提交
375
    }
376
  })
Z
zhaoke 已提交
377 378
}

Z
zhaoke 已提交
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394
const expandNode = (expandedKeysMap) => {
    console.log('expandNode', expandedKeysMap.collapsed)
    for(var key in expandedKeysMap.collapsed){
        if(expandedKeysMap.collapsed[key]){
            expandedKeys.value.forEach((item, index) => {
                if(item === key){
                    expandedKeys.value.splice(index, 1)
                }
            })
        }else{
            expandedKeys.value.push(key)
        }
    }
    setExpandedKeys(currSite.value.id, currProduct.value.id, expandedKeys.value)
}

H
Hao Sun 已提交
395
defineExpose({
aaronchen2k2k's avatar
aaronchen2k2k 已提交
396 397 398 399 400 401 402 403 404 405
  get isCheckable() {
    return checkable.value;
  },
  get isAllCollapsed() {
    return treeRef.value?.isAllCollapsed();
  },
  toggleAllCollapsed() {
    return treeRef.value?.toggleAllCollapsed();
  },
  toggleCheckable,
406 407
  onToolbarClicked,
  loadScripts
H
Hao Sun 已提交
408
});
aaronchen2k2k's avatar
aaronchen2k2k 已提交
409 410 411 412
</script>

<style lang="less" scoped>
.workdir {
aaronchen2k2k's avatar
aaronchen2k2k 已提交
413
  height: calc(100vh - 80px);
aaronchen2k2k's avatar
aaronchen2k2k 已提交
414 415
}
</style>