mirror of
https://github.com/Teamlinker/Teamlinker.git
synced 2025-06-03 03:00:17 +00:00
dev
This commit is contained in:
parent
659d93ad7e
commit
bc9a907ab1
@ -23,6 +23,7 @@
|
||||
"socket.io-client": "^4.6.1",
|
||||
"uuid": "^9.0.0",
|
||||
"vue": "^3.3.4",
|
||||
"vue-i18n": "^9.3.0",
|
||||
"vue-router": "^4.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div style="position: absolute;left: 0;top: 0;width: 100%;height: 100%;display: flex;justify-content: center;align-items: center;background-color: rgba(29,33,41,0.6);z-index: 10000" ref="root">
|
||||
<div style="background-color: white;width: 60%;height:auto;max-height: 80%;border-radius: 5px;display: flex;flex-direction: column">
|
||||
<div style="height: 35px;line-height: 35px;width: 100%;text-align: center;color: rgb(93,93,93);border-bottom: 1px solid gainsboro;flex: 1 1 auto">
|
||||
<b>{{component?title:input?"Input":"Alert"}}</b>
|
||||
<b>{{component?title:input?$t("util.input"):$t("util.alert")}}</b>
|
||||
</div>
|
||||
<div style="display: flex;overflow: auto;box-sizing: border-box;padding: 10px;flex: 0 1 auto;height: calc(100% - 80px);width: 100%">
|
||||
<div style="width: 100%;flex: 1">
|
||||
@ -15,8 +15,8 @@
|
||||
</div>
|
||||
<div style="height: 45px;width: 100%;display: flex;justify-content: flex-end;border-top: 1px solid gainsboro;flex: 1 0 auto">
|
||||
<a-space size="medium">
|
||||
<a-button type="primary" @click="onOk" size="small" html-type="submit" :loading="props.loading?props.loading.value:false">{{(component || input)?"Ok":"Yes"}}</a-button>
|
||||
<a-button type="outline" style="margin-right: 10px" size="small" @click="onClose">{{(component || input)?"Close":"No"}}</a-button>
|
||||
<a-button type="primary" @click="onOk" size="small" html-type="submit" :loading="props.loading?props.loading.value:false">{{(component || input)?$t("util.ok"):$t("util.yes")}}</a-button>
|
||||
<a-button type="outline" style="margin-right: 10px" size="small" @click="onClose">{{(component || input)?$t("util.close"):$t("util.no")}}</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<template v-if="!isEdit">
|
||||
<UserAvatar v-if="showValue" :photo="showValue.photo" :name="showValue.nickname" :organization-user-id="showValue.organizationUserId"></UserAvatar>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">No User</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("common.component.field.basic.fieldEditBasicAssigner.noUser")}}</span>
|
||||
</template>
|
||||
<a-row style="padding-right: 10px" v-else>
|
||||
<a-select allow-search allow-clear v-model="editValue" @search="onSearchAssigner">
|
||||
|
@ -4,7 +4,7 @@
|
||||
<a-space wrap size="mini" v-if="(showValue as ICommon_Model_Project_Release[]).length>0">
|
||||
<ProjectReleasePreview v-for="item in (showValue as ICommon_Model_Project_Release[])" :key="item.id" :project-release-id="item.id" :name="item.name"></ProjectReleasePreview>
|
||||
</a-space>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<a-row style="padding-right: 10px" v-else>
|
||||
<a-space size="mini" wrap>
|
||||
@ -18,7 +18,7 @@
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
Add
|
||||
{{$t("util.add")}}
|
||||
</a-tag>
|
||||
<a-button type="text" @click="onClick">
|
||||
<template #icon>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<a-space wrap size="mini" v-if="(showValue as ICommon_Model_Project_Label[]).length>0">
|
||||
<a-tag v-for="item in (showValue as ICommon_Model_Project_Label[])" color="blue">{{item.name}}</a-tag>
|
||||
</a-space>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<a-row style="padding-right: 10px" v-else>
|
||||
<a-space size="mini" wrap>
|
||||
@ -18,7 +18,7 @@
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
Add
|
||||
{{$t("util.add")}}
|
||||
</a-tag>
|
||||
<a-button type="text" @click="onClick">
|
||||
<template #icon>
|
||||
|
@ -7,10 +7,10 @@
|
||||
</template>
|
||||
<span v-for="item in showValue" style="color: blue">{{item.name}}</span>
|
||||
</a-space>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<a-row style="padding-right: 10px" v-else>
|
||||
<a-cascader v-model="editValue" :field-names="fields" :options="moduleList" placeholder="please select" :format-label="format" check-strictly allow-clear allow-search></a-cascader>
|
||||
<a-cascader v-model="editValue" :field-names="fields" :options="moduleList" :placeholder="$t('placeholder.pleaseSelect')" :format-label="format" check-strictly allow-clear allow-search></a-cascader>
|
||||
<a-button type="text" @click="onClick">
|
||||
<template #icon>
|
||||
<icon-check></icon-check>
|
||||
|
@ -4,10 +4,10 @@
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
<a-select v-model="editValue">
|
||||
<a-option label="low" :value="ECommon_Model_Project_Issue_Priority.LOW"></a-option>
|
||||
<a-option label="medium" :value="ECommon_Model_Project_Issue_Priority.MEDIUM"></a-option>
|
||||
<a-option label="high" :value="ECommon_Model_Project_Issue_Priority.HIGH"></a-option>
|
||||
<a-option label="urgent" :value="ECommon_Model_Project_Issue_Priority.URGENT"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.LOW">{{$t("util.low")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.MEDIUM">{{$t("util.medium")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.HIGH">{{$t("util.hign")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.URGENT">{{$t("util.urgent")}}</a-option>
|
||||
</a-select>
|
||||
<a-button type="text" @click="onClick">
|
||||
<template #icon>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<template v-if="!isEdit">
|
||||
<UserAvatar v-if="showValue" :photo="showValue.photo" :name="showValue.nickname" :organization-user-id="showValue.organizationUserId"></UserAvatar>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">No User</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("common.component.field.basic.fieldEditBasicAssigner.noUser")}}</span>
|
||||
</template>
|
||||
<a-row style="padding-right: 10px" v-else>
|
||||
<a-select allow-search allow-clear v-model="editValue" @search="onSearchReporter">
|
||||
|
@ -4,7 +4,7 @@
|
||||
<a-space wrap size="mini" v-if="showValue">
|
||||
<BoardSprintPreview :key="showValue.id" :board-sprint-id="showValue.id" :name="showValue.name"></BoardSprintPreview>
|
||||
</a-space>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<a-row style="padding-right: 10px" v-else>
|
||||
<a-space size="mini" wrap>
|
||||
|
@ -9,7 +9,7 @@
|
||||
{{showValue.name}}
|
||||
</a-tag>
|
||||
</template>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini" wrap>
|
||||
|
@ -11,7 +11,7 @@
|
||||
</a-tag>
|
||||
</template>
|
||||
</a-space>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini" wrap>
|
||||
@ -25,7 +25,7 @@
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
Add
|
||||
{{$t("util.add")}}
|
||||
</a-tag>
|
||||
<a-button type="text" @click="onSubmit">
|
||||
<template #icon>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<template v-if="!isEdit">
|
||||
<span v-if="showValue">{{showValue}}</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
|
@ -6,7 +6,7 @@
|
||||
<ProjectIssuePreview :name="key+'-'+showValue.uniqueId" :project-issue-id="showValue.id" v-else-if="type===ECommon_Model_Workflow_Node_Field_Type_Label_Type.ISSUE"></ProjectIssuePreview>
|
||||
<BoardSprintPreview :name="showValue.name" :board-sprint-id="showValue.id" v-else-if="type===ECommon_Model_Workflow_Node_Field_Type_Label_Type.SPRINT"></BoardSprintPreview>
|
||||
</template>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
|
@ -6,7 +6,7 @@
|
||||
<ProjectIssuePreview v-for="value in showValue" :key="value.id" :name="key+'-'+value.uniqueId" :project-issue-id="value.id" v-else-if="type===ECommon_Model_Workflow_Node_Field_Type_Label_Type.ISSUE"></ProjectIssuePreview>
|
||||
<BoardSprintPreview v-for="value in showValue" :name="value.name" :board-sprint-id="value.id" v-else-if="type===ECommon_Model_Workflow_Node_Field_Type_Label_Type.SPRINT"></BoardSprintPreview>
|
||||
</a-space>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: grey">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini" wrap>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<template v-if="showValue && showValue.length>0">
|
||||
<a-tag v-for="item in showValue">{{item.value}}</a-tag>
|
||||
</template>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</a-space>
|
||||
<template v-else>
|
||||
<a-space size="mini" wrap>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<template v-if="!isEdit">
|
||||
<span v-if="showValue">{{showValue}}</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
|
@ -3,7 +3,7 @@
|
||||
<template v-if="showValue">
|
||||
<a-tag>{{showValue}}</a-tag>
|
||||
</template>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</a-space>
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<template v-if="!isEdit">
|
||||
<span v-if="showValue">{{showValue}}</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<template v-if="!isEdit">
|
||||
<span v-if="showValue">{{showValue}}</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-space size="mini">
|
||||
|
@ -3,27 +3,27 @@
|
||||
<span v-if="priority==ECommon_Model_Project_Issue_Priority.LOW">
|
||||
<icon-down style="color: lightblue"></icon-down>
|
||||
<template v-if="!onlyIcon">
|
||||
Low
|
||||
{{$t("util.low")}}
|
||||
</template>
|
||||
</span>
|
||||
<span v-else-if="priority==ECommon_Model_Project_Issue_Priority.MEDIUM">
|
||||
<icon-unordered-list style="color: orange"></icon-unordered-list>
|
||||
<template v-if="!onlyIcon">
|
||||
Medium
|
||||
{{$t("util.medium")}}
|
||||
</template>
|
||||
|
||||
</span>
|
||||
<span v-else-if="priority==ECommon_Model_Project_Issue_Priority.HIGH">
|
||||
<icon-up style="color: #ea6e41"></icon-up>
|
||||
<template v-if="!onlyIcon">
|
||||
High
|
||||
{{$t("util.high")}}
|
||||
</template>
|
||||
|
||||
</span>
|
||||
<span v-if="priority==ECommon_Model_Project_Issue_Priority.URGENT">
|
||||
<icon-double-up style="color: red"></icon-double-up>
|
||||
<template v-if="!onlyIcon">
|
||||
Urgent
|
||||
{{$t("util.urgent")}}
|
||||
</template>
|
||||
|
||||
</span>
|
||||
|
@ -190,6 +190,7 @@ import {ICommon_Model_Organization} from "../../../../../common/model/organizati
|
||||
import UserAvatar from "./userAvatar.vue";
|
||||
import {Dialog} from "./dialog/dialog";
|
||||
import {getCurrentInstance} from "vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
type ISSUE={
|
||||
issue:DCSType<ICommon_Model_Project_Issue>,
|
||||
@ -199,6 +200,7 @@ const props=defineProps<{
|
||||
obj:DCSType<ICommon_Route_Res_Notification_Item>
|
||||
}>()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const {t}=useI18n()
|
||||
const onTeam=()=>{
|
||||
const myOrganizationId=SessionStorage.get("organizationId")
|
||||
if(myOrganizationId===props.obj.organization_id) {
|
||||
@ -248,7 +250,7 @@ const onCalendarEvent=()=>{
|
||||
}
|
||||
|
||||
const onAcceptOrganizationInvitation=async ()=>{
|
||||
let ret=await Dialog.confirm(document.body,appContext,"Do you want accept this invitation?")
|
||||
let ret=await Dialog.confirm(document.body,appContext,t("tip.acceptInvitation"))
|
||||
if(ret) {
|
||||
let res=await apiNotification.setStatus({
|
||||
notificationId:props.obj.id,
|
||||
@ -256,7 +258,7 @@ const onAcceptOrganizationInvitation=async ()=>{
|
||||
})
|
||||
if(res?.code==0) {
|
||||
props.obj.status=ECommon_Model_Notification_Status.RESOLVED
|
||||
Message.success("Accepted")
|
||||
Message.success(t("util.accepted"))
|
||||
setTimeout(()=>{
|
||||
eventBus.emit(EClient_EVENTBUS_TYPE.REFRESH_ORGANIZATION_LIST)
|
||||
},1000)
|
||||
@ -267,7 +269,7 @@ const onAcceptOrganizationInvitation=async ()=>{
|
||||
}
|
||||
|
||||
const onRejectOrganizationInvitation=async()=>{
|
||||
let ret=await Dialog.confirm(document.body,appContext,"Do you want reject this invitation?")
|
||||
let ret=await Dialog.confirm(document.body,appContext,t("tip.rejectInvitation"))
|
||||
if(ret) {
|
||||
let res=await apiNotification.setStatus({
|
||||
notificationId:props.obj.id,
|
||||
@ -275,7 +277,7 @@ const onRejectOrganizationInvitation=async()=>{
|
||||
})
|
||||
if(res?.code==0) {
|
||||
props.obj.status=ECommon_Model_Notification_Status.REJECTED
|
||||
Message.success("Rejected")
|
||||
Message.success(t("util.rejected"))
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div style="width: 100%;height: 100%;padding: 5px;box-sizing: border-box" ref="rootEle" @mousedown="onMouseDown">
|
||||
<div style="height: 30px;border-bottom: 1px lightgray solid">
|
||||
<input v-model="keyword" placeholder="type name" style="width: 100%;box-sizing: border-box" @input="onChange">
|
||||
<input v-model="keyword" :placeholder="$t('placeholder.typeName')" style="width: 100%;box-sizing: border-box" @input="onChange">
|
||||
</div>
|
||||
<div class="hover" v-for="item in list" style="height: 40px;display: flex;align-items: center" @click="onClick(item)">
|
||||
<img v-if="item.photo" style="width: 30px;height: 30px;border-radius: 15px" :src="item.photo">
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<div ref="root" @mouseover="onMouseOver" @keydown="onKeyDown" style="padding: 10px" @keyup="onKeyUp" :style="{border:border?'border: 1px solid lightgray;':'0px'}" @copy="onCopy" @dragstart="onDragStart">
|
||||
<div v-for="(item,index) in lineList" :key="index" contenteditable="true" @blur="onBlur(item,$event)" ref="elementList" v-html="RichEditorHandle.handle(item)" @keydown.enter="onEnter(item,index,$event)" @keydown.delete="onDelete(index,item,$event)" style="line-height: 1.5" @focus="onFocus(item,$event)" @mousedown="onMouseDown" @mouseup="onMouseUp" @mousemove="onMouseMove" @dblclick="onDbClick" @paste="onPaste" @click="onClick" placeholder="type / for command,@ for quote person or drop what you want" v-if="!readonly">
|
||||
<div v-for="(item,index) in lineList" :key="index" contenteditable="true" @blur="onBlur(item,$event)" ref="elementList" v-html="RichEditorHandle.handle(item)" @keydown.enter="onEnter(item,index,$event)" @keydown.delete="onDelete(index,item,$event)" style="line-height: 1.5" @focus="onFocus(item,$event)" @mousedown="onMouseDown" @mouseup="onMouseUp" @mousemove="onMouseMove" @dblclick="onDbClick" @paste="onPaste" @click="onClick" :placeholder="$t('placeholder.richText')" v-if="!readonly">
|
||||
</div>
|
||||
<div v-for="(item,index) in lineList" @click="onClick" :key="index+1" v-html="RichEditorHandle.handle(item)" style="line-height: 1.5;min-height: 21px" v-else>
|
||||
</div>
|
||||
|
@ -11,7 +11,7 @@
|
||||
<div class="arco-upload-picture-card" v-else>
|
||||
<div class="arco-upload-picture-card-text">
|
||||
<IconPlus />
|
||||
<div style="margin-top: 10px; font-weight: 600">Upload</div>
|
||||
<div style="margin-top: 10px; font-weight: 600">{{$t("util.upload")}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -43,15 +43,15 @@
|
||||
</a-list-item-meta>
|
||||
<template #actions>
|
||||
<template v-if="organizationUserId===myOrganizationUserId">
|
||||
<a-button type="outline" size="small" style="margin-left: 20px" @click="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="small" style="margin-left: 20px" @click="onProfile">{{$t("util.profile")}}</a-button>
|
||||
</template>
|
||||
<a-row v-else style="flex-direction: column">
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @click="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @click="onProfile">{{$t("util.profile")}}</a-button>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px;margin-top: 10px" @click="onMessage">
|
||||
<template #icon>
|
||||
<icon-message></icon-message>
|
||||
</template>
|
||||
Message
|
||||
{{$t("util.message")}}
|
||||
</a-button>
|
||||
</a-row>
|
||||
</template>
|
||||
@ -70,6 +70,7 @@ import {SessionStorage} from "../storage/session";
|
||||
import {ECommon_IM_Message_EntityType} from "../../../../../common/model/im_unread_message";
|
||||
import {ECommon_User_Online_Status} from "../../../../../common/types";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const loading=ref(true)
|
||||
const props=defineProps<{
|
||||
@ -89,6 +90,7 @@ const showCloseable=ref(false)
|
||||
const root=ref(null);
|
||||
const name=ref("")
|
||||
const photo=ref("")
|
||||
const {t}=useI18n()
|
||||
const status=ref(ECommon_User_Online_Status.OFFLINE)
|
||||
watch(()=>[props.name,props.photo],()=>{
|
||||
name.value=props.name
|
||||
@ -107,7 +109,7 @@ const imgName=computed(()=>{
|
||||
const info=ref<DCSType<ICommon_Model_Organization_User>>(null)
|
||||
const onProfile=()=>{
|
||||
if(info.value.organization_id!==SessionStorage.get("organizationId")) {
|
||||
Message.error("you should switch to the specific organization")
|
||||
Message.error(t("tip.switchToSpecificOrganization"))
|
||||
return
|
||||
}
|
||||
eventBus.emit(EClient_EVENTBUS_TYPE.OPEN_PEOPLE_PROFILE,props.organizationUserId);
|
||||
@ -144,7 +146,7 @@ const onPopup=async (visible:boolean)=>{
|
||||
}
|
||||
const onMessage=()=>{
|
||||
if(info.value.organization_id!==SessionStorage.get("organizationId")) {
|
||||
Message.error("you should switch to the specific organization")
|
||||
Message.error(t("tip.switchToSpecificOrganization"))
|
||||
return
|
||||
}
|
||||
eventBus.emit(EClient_EVENTBUS_TYPE.OPEN_IM_CHAT,props.organizationUserId,ECommon_IM_Message_EntityType.USER)
|
||||
|
@ -28,15 +28,15 @@
|
||||
</a-list-item-meta>
|
||||
<template #actions>
|
||||
<template v-if="organizationUserId===myOrganizationUserId">
|
||||
<a-button type="outline" size="small" style="margin-left: 20px" @mousedown="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="small" style="margin-left: 20px" @mousedown="onProfile">{{$t("util.profile")}}</a-button>
|
||||
</template>
|
||||
<a-row v-else style="flex-direction: column">
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @mousedown="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @mousedown="onProfile">{{$t("util.profile")}}</a-button>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px;margin-top: 10px" @mousedown="onMessage">
|
||||
<template #icon>
|
||||
<icon-message></icon-message>
|
||||
</template>
|
||||
Message
|
||||
{{$t("util.message")}}
|
||||
</a-button>
|
||||
</a-row>
|
||||
</template>
|
||||
|
@ -35,7 +35,8 @@ export enum EClient_EVENTBUS_TYPE {
|
||||
FINDER_OPEN_WINDOW="finder_open_window",
|
||||
REFRESH_ORGANIZATION_LIST="refresh_organization_list",
|
||||
REFRESH_NOTIFICATION_UNREAD="refresh_notification_unread",
|
||||
REFRESH_MISS_CALL_UNREAD="refresh_miss_call_unread"
|
||||
REFRESH_MISS_CALL_UNREAD="refresh_miss_call_unread",
|
||||
USER_LOGIN_EXPIRED="user_login_expired"
|
||||
}
|
||||
|
||||
interface IClient_EventBus_Func {
|
||||
@ -73,6 +74,7 @@ interface IClient_EventBus_Func {
|
||||
[EClient_EVENTBUS_TYPE.REFRESH_MISS_CALL_UNREAD]:()=>void
|
||||
[EClient_EVENTBUS_TYPE.OPEN_PROJECT_SPRINT_KANBAN_PROFILE]:(projectId:string,boardId:string,boardSprintId:string)=>void
|
||||
[EClient_EVENTBUS_TYPE.OPEN_PROJECT_BOARD_PROFILE]:(projectId:string,boardId:string)=>void
|
||||
[EClient_EVENTBUS_TYPE.USER_LOGIN_EXPIRED]:()=>void
|
||||
}
|
||||
|
||||
interface IClient_EventBus_Emit_Func {
|
||||
|
18
code/client/src/business/common/i18n/i18n.ts
Normal file
18
code/client/src/business/common/i18n/i18n.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import en from "../../../../../common/i18n/en"
|
||||
import {createI18n} from "vue-i18n";
|
||||
import zh from "../../../../../common/i18n/zh";
|
||||
|
||||
const messages={
|
||||
en,
|
||||
zh
|
||||
}
|
||||
|
||||
const language=(navigator.language || "en").toLowerCase()
|
||||
const i18n=createI18n({
|
||||
legacy:false,
|
||||
locale:localStorage.getItem("lang") || language.split("-")[0] || "en",
|
||||
fallbackLocale:"en",
|
||||
messages
|
||||
})
|
||||
|
||||
export default i18n
|
@ -5,6 +5,7 @@ import {ECommon_Model_Finder_Item_Type} from "../../../../../common/model/finder
|
||||
import {EClient_Drag_Type} from "../../../teamOS/common/directive/drag";
|
||||
import {ECommon_IM_Message_ContentType} from "../../../../../common/model/im_user_message";
|
||||
import {ECommon_Content_Line_Config_Type, ICommon_Content_Line} from "../../../../../common/model/content";
|
||||
import i18n from "@/business/common/i18n/i18n";
|
||||
|
||||
export function getMemberIdFromRoleMember(item:ICommon_Route_Res_Role_Member_Item){
|
||||
if(item.memberType==ECommon_Model_Organization_Member_Type.DEFAULT) {
|
||||
@ -45,7 +46,8 @@ export function dialogFuncGenerator({func,form}:{
|
||||
let res=await func()
|
||||
if(typeof(res)=="object") {
|
||||
if(res?.code==0) {
|
||||
Message.success("operation success")
|
||||
const {t}=i18n.global
|
||||
Message.success(t("tip.operationSuccess"))
|
||||
return res
|
||||
} else {
|
||||
Message.error(res.msg);
|
||||
|
@ -2,8 +2,8 @@
|
||||
<a-layout style="height: 100%">
|
||||
<a-layout-sider :resize-directions="['right']">
|
||||
<a-menu style="width: 100%" @menu-item-click="onSubMenuClick" :default-selected-keys="['profile']">
|
||||
<a-menu-item key="profile">Profile</a-menu-item>
|
||||
<a-menu-item key="accountSetting">Account Setting</a-menu-item>
|
||||
<a-menu-item key="profile">{{$t("controller.app.account.account.profile")}}</a-menu-item>
|
||||
<a-menu-item key="accountSetting">{{$t("controller.app.account.account.accountSetting")}}</a-menu-item>
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout-content style="flex-direction: column;display: flex;padding: 10px">
|
||||
|
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<a-collapse :default-active-key="['wallpaper']">
|
||||
<a-collapse-item key="wallpaper" header="Wallpaper">
|
||||
<a-collapse-item key="wallpaper" :header="$t('util.wallpaper')">
|
||||
<a-form :model="formWallPaper" style="width: 80%" @submitSuccess="onSubmitWallpaper">
|
||||
<a-form-item field="photo" label="wallpaper">
|
||||
<a-form-item field="photo" :label="$t('util.wallpaper')">
|
||||
<Upload :default-uri="formWallPaper.photo" types=".png,.jpg,.jpeg,.gif,.bmp,.svg,.webp" @upload="onUploadWallpaper"></Upload>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-space size="large">
|
||||
<a-button html-type="submit" type="primary">Save</a-button>
|
||||
<a-button html-type="button" status="danger" v-if="formWallPaper.photo" @click="onClearWallpaper">Clear</a-button>
|
||||
<a-button html-type="submit" type="primary">{{$t("util.ok")}}</a-button>
|
||||
<a-button html-type="button" status="danger" v-if="formWallPaper.photo" @click="onClearWallpaper">{{$t("util.clear")}}</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -1,22 +1,22 @@
|
||||
<template>
|
||||
<a-form :model="form" style="width: 80%" @submitSuccess="onSubmit">
|
||||
<a-form-item field="photo" label="avatar">
|
||||
<a-form-item field="photo" :label="$t('util.avatar')">
|
||||
<Upload :default-uri="form.photo" types=".png,.jpg,.jpeg,.gif,.bmp,.svg" @upload="onUpload"></Upload>
|
||||
</a-form-item>
|
||||
<a-form-item label="username">
|
||||
{{form.username}}
|
||||
</a-form-item>
|
||||
<a-form-item field="password" label="password">
|
||||
<a-form-item field="password" :label="$t('util.password')">
|
||||
<a-input-password v-model="form.password"></a-input-password>
|
||||
</a-form-item>
|
||||
<a-form-item field="repeatPassword" label="repeat password" v-if="form.password">
|
||||
<a-form-item field="repeatPassword" :label="$t('util.repeatPassword')" v-if="form.password">
|
||||
<a-input-password v-model="form.repeatPassword"></a-input-password>
|
||||
</a-form-item>
|
||||
<a-form-item field="sign" label="sign">
|
||||
<a-form-item field="sign" :label="$t('util.sign')">
|
||||
<a-input v-model="form.sign"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button html-type="submit" type="primary">Save</a-button>
|
||||
<a-button html-type="submit" type="primary">{{$t("util.save")}}</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
@ -29,6 +29,7 @@ import {apiUser} from "../../../common/request/request";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {SessionStorage} from "../../../common/storage/session";
|
||||
import md5 from "blueimp-md5";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const store=useDesktopStore()
|
||||
const form=reactive({
|
||||
@ -39,9 +40,10 @@ const form=reactive({
|
||||
repeatPassword:"",
|
||||
uploadUriId:""
|
||||
})
|
||||
const {t}=useI18n()
|
||||
const onSubmit=async ()=>{
|
||||
if(form.password && form.password!==form.repeatPassword) {
|
||||
Message.error("password not match")
|
||||
Message.error(t("tip.passwordNotMatch"))
|
||||
return;
|
||||
}
|
||||
let arrPromise=[]
|
||||
@ -63,7 +65,7 @@ const onSubmit=async ()=>{
|
||||
}
|
||||
let [res1,res2]=await Promise.all(arrPromise)
|
||||
if(res1?.code==0) {
|
||||
Message.success("update success")
|
||||
Message.success(t("tip.updateSuccess"))
|
||||
store.$refreshUser();
|
||||
} else {
|
||||
Message.error(res1.msg)
|
||||
|
@ -11,7 +11,7 @@
|
||||
/>
|
||||
<a-divider :margin="1"></a-divider>
|
||||
<a-row style="display: flex;justify-content: space-between;margin-top: 10px;align-items: center">
|
||||
<span style="font-size: small;color: gray">My Calendars</span>
|
||||
<span style="font-size: small;color: gray">{{$t("controller.app.calendar.calendar.myCalendars")}}</span>
|
||||
<a-button size="mini" type="text" @click="onAddCalendar">
|
||||
<template #icon>
|
||||
<icon-plus style="color: gray"></icon-plus>
|
||||
@ -40,7 +40,7 @@
|
||||
<a-layout-content style="flex-direction: column;display: flex;padding: 10px;">
|
||||
<a-row style="flex: 0 0 40px;display: flex;justify-content: space-between;justify-items: center;flex-wrap: nowrap">
|
||||
<a-space size="mini">
|
||||
<a-button type="primary" size="mini" @click="onToday">Today</a-button>
|
||||
<a-button type="primary" size="mini" @click="onToday">{{$t("controller.app.calendar.calendar.today")}}</a-button>
|
||||
<a-button type="text" @click="onPrevious">
|
||||
<template #icon>
|
||||
<icon-left style="color: rgb(95,99,104);font-size: large"></icon-left>
|
||||
@ -55,25 +55,25 @@
|
||||
{{calendarType=="day"?pickerValue.format("YYYY-MM-DD"):pickerValue.format("YYYY-MM")}}
|
||||
</span>
|
||||
</a-space>
|
||||
<a-input style="width: 40%" placeholder="type event name" v-model="searchForm.keyword" allow-clear @input="onSearch">
|
||||
<a-input style="width: 40%" :placeholder="$t('placeholder.typeEventName')" v-model="searchForm.keyword" allow-clear @input="onSearch">
|
||||
<template #append>
|
||||
<a-popover position="br" @popup-visible-change="visible => !visible && onSearch()">
|
||||
<icon-arrow-down style="margin-left: 10px;cursor: pointer"></icon-arrow-down>
|
||||
<template #content>
|
||||
<a-form :model="{}" layout="vertical">
|
||||
<a-form-item label="calendar">
|
||||
<a-form-item :label="$t('util.calendar')">
|
||||
<a-select size="small" v-model="searchForm.calendarId">
|
||||
<a-option value="all">All</a-option>
|
||||
<a-option value="all">{{$t("util.all")}}</a-option>
|
||||
<a-option v-for="item in calendarList" :value="item.id">{{item.name}}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="start date">
|
||||
<a-form-item :label="$t('util.startDate')">
|
||||
<a-date-picker v-model="searchForm.startDate"></a-date-picker>
|
||||
</a-form-item>
|
||||
<a-form-item label="end date">
|
||||
<a-form-item :label="$t('util.endDate')">
|
||||
<a-date-picker v-model="searchForm.endDate"></a-date-picker>
|
||||
</a-form-item>
|
||||
<a-form-item label="location">
|
||||
<a-form-item :label="$t('util.location')">
|
||||
<a-input size="small" v-model="searchForm.location"></a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@ -83,9 +83,9 @@
|
||||
</a-input>
|
||||
<a-space size="mini">
|
||||
<a-radio-group type="button" v-model="calendarType" size="small">
|
||||
<a-radio value="day">Day</a-radio>
|
||||
<a-radio value="week">Week</a-radio>
|
||||
<a-radio value="month">Month</a-radio>
|
||||
<a-radio value="day">{{$t("controller.app.calendar.calendar.day")}}</a-radio>
|
||||
<a-radio value="week">{{$t("controller.app.calendar.calendar.week")}}</a-radio>
|
||||
<a-radio value="month">{{$t("controller.app.calendar.calendar.month")}}</a-radio>
|
||||
</a-radio-group>
|
||||
<a-button type="text" @click="onShowSetting">
|
||||
<template #icon>
|
||||
@ -103,17 +103,17 @@
|
||||
<CalendarEventSearch :list="searchResultList" :timezone="setting.timezone" v-else-if="searchForm.keyword" style="width: 100%;height: 100%" @edit="onEditCalendarEvent" @delete="onDeleteCalendarEvent"></CalendarEventSearch>
|
||||
</a-row>
|
||||
</a-layout-content>
|
||||
<a-drawer :popup-container="root" :visible="settingVisible" @ok="onSetting" unmount-on-close title="Calendar Global Setting" :closable="false" @cancel="settingVisible=false" :width="400" id="calendarSetting" :drawer-style="{zIndex:100}">
|
||||
<a-drawer :popup-container="root" :visible="settingVisible" @ok="onSetting" unmount-on-close :title="$t('controller.app.calendar.calendar.calendarGlobalSetting')" :closable="false" @cancel="settingVisible=false" :width="400" id="calendarSetting" :drawer-style="{zIndex:100}">
|
||||
<a-form :model="{}" layout="vertical">
|
||||
<a-form-item label="follow device timezone">
|
||||
<a-form-item :label="$t('controller.app.calendar.calendar.followDeviceTimeZone')">
|
||||
<a-switch v-model="settingEdit.followDevice"></a-switch>
|
||||
</a-form-item>
|
||||
<a-form-item label="timezone" v-if="!settingEdit.followDevice">
|
||||
<a-form-item :label="$t('util.timeZone')" v-if="!settingEdit.followDevice">
|
||||
<a-select v-model="settingEdit.timezone">
|
||||
<a-option v-for="item in timezones" :value="item.id">{{item.label}}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="start week day">
|
||||
<a-form-item :label="$t('controller.app.calendar.calendar.startWeekDay')">
|
||||
<a-select v-model="settingEdit.start_week_day">
|
||||
<a-option v-for="item in ECommon_Calendar_WeekDay" :value="item">{{calendarWeekDayName[item]}}</a-option>
|
||||
</a-select>
|
||||
@ -163,6 +163,8 @@ import {SessionStorage} from "../../../common/storage/session";
|
||||
import {ICommon_Route_Res_Calendar_ListEvent_Item} from "../../../../../../common/routes/response";
|
||||
import CalendarEventSearch from "./calendarEventSearch.vue";
|
||||
import {debounce} from "../../../common/util/helper";
|
||||
import calendar from "../../../../../../common/routes/calendar";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
calendarEventId?:string
|
||||
@ -197,6 +199,7 @@ const searchForm=reactive({
|
||||
})
|
||||
const searchResultList=ref<DCSType<ICommon_Route_Res_Calendar_ListEvent_Item>[]>([])
|
||||
let searchDebounce=null
|
||||
const {t}=useI18n()
|
||||
provide(injectCalendarSetting,setting)
|
||||
const startDay=computed(()=>{
|
||||
let start_week_day=setting.value?.start_week_day
|
||||
@ -309,13 +312,13 @@ const onEditCalendar=async (item)=>{
|
||||
}
|
||||
}
|
||||
const onDeleteCalendar=async (item)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"do you want to delete this calendar?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteCalendar"))
|
||||
if(ret) {
|
||||
let res=await apiCalendar.removeCalendar({
|
||||
calendarId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
if(selectedCalendar.value.includes(item.id)) {
|
||||
selectedCalendar.value=selectedCalendar.value.splice(selectedCalendar.value.indexOf(item.id),1)
|
||||
}
|
||||
@ -331,7 +334,7 @@ const onSetting=async ()=>{
|
||||
startWeekDay:settingEdit.value.start_week_day
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("update success")
|
||||
Message.success(t("tip.updateSuccess"))
|
||||
settingVisible.value=false
|
||||
getSetting()
|
||||
}
|
||||
@ -392,7 +395,7 @@ const onAddCalendarEvent=async (date:moment.Moment, point:{
|
||||
}
|
||||
const saveCalendarEvent=async (title:string, dateInfo:CalendarEventModelType, calendarId:string)=>{
|
||||
if(dateInfo.end<dateInfo.start) {
|
||||
Message.error("end date can't less than start date")
|
||||
Message.error(t("tip.endDateLess"))
|
||||
return
|
||||
}
|
||||
let res=await apiCalendar.addCalendarEvent({
|
||||
@ -476,13 +479,13 @@ const listCalendarEvent=async ()=>{
|
||||
}
|
||||
}
|
||||
const onDeleteCalendarEvent=async (event:IClient_Calendar_Info)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this event?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteEvent"))
|
||||
if(ret) {
|
||||
let res=await apiCalendar.removeCalendarEvent({
|
||||
calendarEventId:event.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
listCalendarEvent()
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<a-form ref="eleForm" style="width: 80%" :model="form">
|
||||
<a-form-item label="name" field="name" required>
|
||||
<a-form-item :label="$t('util.name')" field="name" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="color" field="color" required>
|
||||
<a-form-item :label="$t('util.color')" field="color" required>
|
||||
<a-radio-group v-model="form.color">
|
||||
<a-radio v-for="item in ECommon_Calendar_Color" :value="item">
|
||||
<div :style="{backgroundColor:item}" style="display: inline-block;width: 14px;height: 14px;margin-top: 3px;border-radius: 2px"></div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
<template #label>
|
||||
<icon-info-circle style="font-size: medium"></icon-info-circle>
|
||||
</template>
|
||||
<a-input placeholder="New Event Title" v-model="form.name"></a-input>
|
||||
<a-input :placeholder="$t('placeholder.newEventTitle')" v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item field="dateInfo" required hide-asterisk>
|
||||
<template #label>
|
||||
@ -33,8 +33,8 @@
|
||||
</div>
|
||||
<div style="height: 35px">
|
||||
<a-space style="float: right;margin-right: 10px">
|
||||
<a-button type="secondary" size="small" @click="emit('more',form.name,form.dateInfo,form.resourceId)">More Option</a-button>
|
||||
<a-button type="primary" size="small" @click="checkValid">Save</a-button>
|
||||
<a-button type="secondary" size="small" @click="emit('more',form.name,form.dateInfo,form.resourceId)">{{$t("controller.app.calendar.calendarEventAddSimple.moreOption")}}</a-button>
|
||||
<a-button type="primary" size="small" @click="checkValid">{{$t("util.save")}}</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -14,9 +14,9 @@
|
||||
</a-row>
|
||||
<a-row style="height: 40px">
|
||||
<a-space wrap>
|
||||
All Day:
|
||||
{{$t("controller.app.calendar.calendarEventDateEdit.allDay")}}:
|
||||
<a-switch :checked-value="1" :unchecked-value="0" v-model="data.isAllDay" size="small" @change="onChangeAllDay"></a-switch>
|
||||
Repeat:
|
||||
{{$t("controller.app.calendar.calendarEventDateEdit.repeat")}}:
|
||||
<a-select style="width: 110px" size="small" v-model="data.recurring">
|
||||
<a-option :value="ECommon_Calendar_Recurring_Type.NONE">No</a-option>
|
||||
<a-option :value="ECommon_Calendar_Recurring_Type.DAY">Day</a-option>
|
||||
@ -25,13 +25,13 @@
|
||||
<a-option :value="ECommon_Calendar_Recurring_Type.MONTH">Month</a-option>
|
||||
</a-select>
|
||||
<template v-if="data.recurring===ECommon_Calendar_Recurring_Type.WEEK">
|
||||
Select Weekday:
|
||||
{{$t("controller.app.calendar.calendarEventDateEdit.selectWeekday")}}:
|
||||
<a-select size="small" style="width: 130px" v-model="recurryingWeekDay" @change="onChangeRecurry">
|
||||
<a-option v-for="item in ECommon_Calendar_WeekDay" :value="item">{{calendarWeekDayName[item]}}</a-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="data.recurring===ECommon_Calendar_Recurring_Type.MONTH">
|
||||
Input Day:
|
||||
{{$t("controller.app.calendar.calendarEventDateEdit.inputDay")}}:
|
||||
<a-input-number :min="1" :max="31" v-model="recurryingMonthDay" style="width: 100px" @change="onChangeRecurry" size="small"></a-input-number>
|
||||
</template>
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
<template #label>
|
||||
<icon-info-circle style="font-size: medium"></icon-info-circle>
|
||||
</template>
|
||||
<a-input placeholder="New Event Title" v-model="form.name" v-if="isSelf"></a-input>
|
||||
<a-input :placeholder="$t('placeholder.newEventTitle')" v-model="form.name" v-if="isSelf"></a-input>
|
||||
<template v-else>
|
||||
{{form.name}}
|
||||
</template>
|
||||
@ -16,13 +16,13 @@
|
||||
<CalendarEventDateEdit :timezone="timezone" :data="form.date"></CalendarEventDateEdit>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-divider orientation="left" :margin="1">Advanced</a-divider>
|
||||
<a-divider orientation="left" :margin="1">{{$t("controller.app.calendar.calendarEventEdit.advanced")}}</a-divider>
|
||||
</a-form-item>
|
||||
<a-form-item field="location">
|
||||
<template #label>
|
||||
<icon-location style="font-size: medium"></icon-location>
|
||||
</template>
|
||||
<a-input placeholder="location" v-model="form.location" v-if="isSelf"></a-input>
|
||||
<a-input :placeholder="$t('placeholder.location')" v-model="form.location" v-if="isSelf"></a-input>
|
||||
<template v-else>
|
||||
{{form.location?form.location:"None"}}
|
||||
</template>
|
||||
@ -32,21 +32,21 @@
|
||||
<icon-notification style="font-size: medium"></icon-notification>
|
||||
</template>
|
||||
<a-select v-model="form.reminder" v-if="isSelf">
|
||||
<a-option :value="0">No Reminder</a-option>
|
||||
<a-option :value="5">5 Min Before</a-option>
|
||||
<a-option :value="15">15 Min Before</a-option>
|
||||
<a-option :value="30">30 Min Before</a-option>
|
||||
<a-option :value="60">1 Hour Before</a-option>
|
||||
<a-option :value="600">6 Hour Before</a-option>
|
||||
<a-option :value="0">{{$t("controller.app.calendar.calendarEventEdit.noReminder")}}</a-option>
|
||||
<a-option :value="5">{{$t("controller.app.calendar.calendarEventEdit.fiveMinBefore")}}</a-option>
|
||||
<a-option :value="15">{{$t("controller.app.calendar.calendarEventEdit.fifteenMinBefore")}}</a-option>
|
||||
<a-option :value="30">{{$t("controller.app.calendar.calendarEventEdit.thirtyMinBefore")}}</a-option>
|
||||
<a-option :value="60">{{$t("controller.app.calendar.calendarEventEdit.oneHourBefore")}}</a-option>
|
||||
<a-option :value="600">{{$t("controller.app.calendar.calendarEventEdit.sixHourBefore")}}</a-option>
|
||||
</a-select>
|
||||
<template v-else>
|
||||
{{({
|
||||
"0":"No Reminder",
|
||||
"5":"5 Min Before",
|
||||
"15":"15 Min Before",
|
||||
"30":"30 Min Before",
|
||||
"60":"1 Hour Before",
|
||||
"600":"6 Hour Before"
|
||||
"0":$t("controller.app.calendar.calendarEventEdit.noReminder"),
|
||||
"5":$t("controller.app.calendar.calendarEventEdit.fiveMinBefore"),
|
||||
"15":$t("controller.app.calendar.calendarEventEdit.fifteenMinBefore"),
|
||||
"30":$t("controller.app.calendar.calendarEventEdit.thirtyMinBefore"),
|
||||
"60":$t("controller.app.calendar.calendarEventEdit.oneHourBefore"),
|
||||
"600":$t("controller.app.calendar.calendarEventEdit.sixHourBefore")
|
||||
})[form.reminder]}}
|
||||
</template>
|
||||
</a-form-item>
|
||||
@ -73,11 +73,11 @@
|
||||
<a-switch v-model="form.meeting"></a-switch>
|
||||
<a-popover position="right" v-if="form.meeting" trigger="click">
|
||||
<a-button type="primary" status="success" style="margin-left: 20px">
|
||||
Start Meeting
|
||||
{{$t("controller.app.calendar.calendarEventEdit.startMeeting")}}
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-row style="flex-direction: column;align-items: center">
|
||||
<a-input size="small" placeholder="type user name" v-model="searchUserKey"></a-input>
|
||||
<a-input size="small" :placeholder="$t('placeholder.typeUserName')" v-model="searchUserKey"></a-input>
|
||||
<a-table style="width: 100%;margin-top: 10px" row-key="organizationUserId" :columns="columns" :data="(form.guestList as any).filter(item=>(item.organizationUserId!==organizationUserId && item.nickname.includes(searchUserKey)))" :row-selection="rowSelection" v-model:selected-keys="selectKeys" :pagination="false">
|
||||
<template #name="{record}">
|
||||
<UserAvatar :organization-user-id="record.organizationUserId" :name="record.nickname" :photo="record.photo"></UserAvatar>
|
||||
@ -92,7 +92,7 @@
|
||||
</template>
|
||||
</template>
|
||||
<a-button type="primary" status="success" @click="onMeeting" v-else>
|
||||
Join Meeting
|
||||
{{$t("controller.app.calendar.calendarEventEdit.joinMeeting")}}
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item field="guestList">
|
||||
@ -139,6 +139,7 @@ import UserAvatar from "../../../common/component/userAvatar.vue";
|
||||
import {TableRowSelection} from "@arco-design/web-vue/es/table/interface";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../common/event/event";
|
||||
import {ECommon_Model_Organization_Member_Type} from "../../../../../../common/model/organization";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
type:"add"|"edit",
|
||||
@ -166,9 +167,10 @@ const rowSelection=ref<TableRowSelection>({
|
||||
showCheckedAll:true,
|
||||
onlyCurrent:false
|
||||
})
|
||||
const {t}=useI18n()
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
title: t("util.name"),
|
||||
slotName: 'name',
|
||||
}
|
||||
]
|
||||
@ -264,7 +266,7 @@ onDialogOk(dialogFuncGenerator({
|
||||
form:()=>formEle.value,
|
||||
func:()=>{
|
||||
if(form.date.end<form.date.start) {
|
||||
Message.error("end date can't less than start date")
|
||||
Message.error(t("tip.endDateLess"))
|
||||
return false
|
||||
}
|
||||
if(isSelf.value) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-space wrap>
|
||||
<UserAvatar v-for="value in showValue" v-if="showValue && showValue.length>0" :organization-user-id="value.organizationUserId" :name="value.nickname" :photo="value.photo" :key="value.userId" @close="onClose" :closeable="true"></UserAvatar>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">None</span>
|
||||
<span v-else style="line-height: 30px;width: 100%;color: gray">{{$t("util.none")}}</span>
|
||||
<a-select v-model="addValue" allow-search @search="onSearch" v-if="showInput" @change="onChange">
|
||||
<a-option v-for="item1 in searchValueList" :label="item1.nickname" :value="item1.userId"></a-option>
|
||||
</a-select>
|
||||
|
@ -44,11 +44,11 @@
|
||||
<div style="flex: 1 1 auto;display: flex;align-items: center">
|
||||
<a-popover position="right" trigger="click" v-if="isSelf">
|
||||
<a-button type="primary" status="success" size="mini">
|
||||
Start Meeting
|
||||
{{$t("controller.app.calendar.calendarEventEdit.startMeeting")}}
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-row style="flex-direction: column;align-items: center">
|
||||
<a-input size="small" placeholder="type user name" v-model="searchUserKey"></a-input>
|
||||
<a-input size="small" :placeholder="$t('placeholder.typeUserName')" v-model="searchUserKey"></a-input>
|
||||
<a-table style="width: 100%;margin-top: 10px" row-key="organizationUserId" :columns="columns" :data="(calendarEventInfo.guestList as any).filter(item=>(item.organizationUserId!==organizationUserId && item.nickname.includes(searchUserKey)))" :row-selection="rowSelection" v-model:selected-keys="selectKeys" :pagination="false">
|
||||
<template #name="{record}">
|
||||
<UserAvatar :organization-user-id="record.organizationUserId" :name="record.nickname" :photo="record.photo"></UserAvatar>
|
||||
@ -59,7 +59,7 @@
|
||||
</template>
|
||||
</a-popover>
|
||||
<a-button type="primary" status="success" size="mini" @click="onMeeting" v-else>
|
||||
Join Meeting
|
||||
{{$t("controller.app.calendar.calendarEventEdit.joinMeeting")}}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -73,7 +73,7 @@
|
||||
</template>
|
||||
<template v-else>
|
||||
<UserAvatar :organization-user-id="selectedEvent.created_by.organizationUserId" :name="selectedEvent.created_by.nickname" :photo="selectedEvent.created_by.photo"></UserAvatar>
|
||||
invited you
|
||||
{{$t("controller.app.calendar.calendarEventShortView.invitedYou")}}
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@ -95,6 +95,7 @@ import {ICommon_Route_Res_Calendar_Event_Info} from "../../../../../../common/ro
|
||||
import {TableRowSelection} from "@arco-design/web-vue/es/table/interface";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../common/event/event";
|
||||
import {ECommon_Model_Organization_Member_Type} from "../../../../../../common/model/organization";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const emit=defineEmits<{
|
||||
edit:[event:IClient_Calendar_Info],
|
||||
@ -117,9 +118,10 @@ const rowSelection=ref<TableRowSelection>({
|
||||
showCheckedAll:true,
|
||||
onlyCurrent:false
|
||||
})
|
||||
const {t}=useI18n()
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
title: t("util.name"),
|
||||
slotName: 'name',
|
||||
}
|
||||
]
|
||||
|
@ -25,7 +25,7 @@
|
||||
</a-row>
|
||||
</a-row>
|
||||
<template v-else-if="mode===EClient_Finder_Mode.SEARCH">
|
||||
SEARCH RESULT:
|
||||
{{$t("controller.app.finder.finder.searchResult")}}:
|
||||
</template>
|
||||
<a-row>
|
||||
<a-input-search size="mini" style="background-color: white;border: 1px lightgray solid" @search="onSearch"></a-input-search>
|
||||
|
@ -21,10 +21,10 @@
|
||||
<a-dropdown trigger="hover" position="bl">
|
||||
<icon-more style="color: gray"></icon-more>
|
||||
<template #content>
|
||||
<a-doption @click="onRefresh(nodeData)">Refresh</a-doption>
|
||||
<a-doption @click="onRenameFolder(nodeData)" v-if="nodeData.key">Rename</a-doption>
|
||||
<a-doption @click="onAddFolder(nodeData)">Add Folder</a-doption>
|
||||
<a-doption v-if="nodeData.key" @click="onRemove(nodeData)">Remove</a-doption>
|
||||
<a-doption @click="onRefresh(nodeData)">{{$t("util.refresh")}}</a-doption>
|
||||
<a-doption @click="onRenameFolder(nodeData)" v-if="nodeData.key">{{$t("util.rename")}}</a-doption>
|
||||
<a-doption @click="onAddFolder(nodeData)">{{$t("controller.app.finder.finderFolderTree.addFolder")}}</a-doption>
|
||||
<a-doption v-if="nodeData.key" @click="onRemove(nodeData)">{{$t("util.remove")}}</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
@ -37,6 +37,7 @@ import {apiFinder} from "../../../common/request/request";
|
||||
import {getRootNavigatorRef} from "../../../../teamOS/common/component/navigator/navigator";
|
||||
import {Dialog} from "../../../common/component/dialog/dialog";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../common/event/event";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
interface FolderTree {
|
||||
title:string,
|
||||
@ -52,6 +53,7 @@ const rename=ref("")
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const root=getRootNavigatorRef()
|
||||
const expandKeys=ref<string[]>([])
|
||||
const {t}=useI18n()
|
||||
const folderTree=ref<FolderTree[]>([
|
||||
{
|
||||
title:"Desktop",
|
||||
@ -96,7 +98,7 @@ const onConfirmRenameFolder=async (nodeData)=>{
|
||||
}
|
||||
|
||||
const onAddFolder=async (nodeData)=>{
|
||||
let ret=await Dialog.input(root.value,appContext,"please type folder name")
|
||||
let ret=await Dialog.input(root.value,appContext,t("tip.typeFolderName"))
|
||||
if(ret) {
|
||||
let res=await apiFinder.createFolder({
|
||||
name:ret,
|
||||
@ -145,7 +147,7 @@ const findParentNodeData=(key:string,node?)=>{
|
||||
}
|
||||
|
||||
const onRemove=async (nodeData)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"do you want to delete this folder?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteFolder"))
|
||||
if(ret) {
|
||||
let res=await apiFinder.delete({
|
||||
finderItemId:nodeData.key
|
||||
|
@ -27,6 +27,7 @@ import {EClient_Drag_Type, IClient_Drag_Element} from "../../../../teamOS/common
|
||||
import {DropParam} from "../../../../teamOS/common/directive/drop";
|
||||
import {SessionStorage} from "../../../common/storage/session";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import i18n from "@/business/common/i18n/i18n";
|
||||
|
||||
export class FinderHandle {
|
||||
private itemList=ref<Icon[]>([])
|
||||
@ -65,7 +66,8 @@ export class FinderHandle {
|
||||
{
|
||||
title:"New Folder",
|
||||
func:async value => {
|
||||
let ret=await Dialog.input(this.root.value.$el?this.root.value.$el:this.root.value,this.appContext,"please type new folder name");
|
||||
let {t}=i18n.global
|
||||
let ret=await Dialog.input(this.root.value.$el?this.root.value.$el:this.root.value,this.appContext,t("tip.typeNewFolderName"));
|
||||
if(ret) {
|
||||
let res=await apiFinder.createFolder({
|
||||
...(this.folderId && {
|
||||
@ -255,7 +257,8 @@ export class FinderHandle {
|
||||
let valueList=selectedSelectableItems.map(item=>{
|
||||
return item.getAttribute("dragValue")
|
||||
})
|
||||
let ret=await Dialog.confirm(this.root.value.$el?this.root.value.$el:this.root.value,this.appContext,"Do you want to delete these items?")
|
||||
const {t}=i18n.global
|
||||
let ret=await Dialog.confirm(this.root.value.$el?this.root.value.$el:this.root.value,this.appContext,t("tip.deleteItems"))
|
||||
if(ret) {
|
||||
await Promise.allSettled(valueList.map(value=>{
|
||||
return apiFinder.delete({
|
||||
@ -374,7 +377,8 @@ export class FinderHandle {
|
||||
|
||||
private async onOpenShortcut(item:DCSType<ICommon_Model_Finder_Item>) {
|
||||
if(item.organization_id!==SessionStorage.get("organizationId")) {
|
||||
Message.error("you should switch to the specific organization")
|
||||
const {t}=i18n.global
|
||||
Message.error(t("tip.switchToSpecificOrganization"))
|
||||
return
|
||||
}
|
||||
switch (item.shortcut_type) {
|
||||
|
@ -1,225 +1,225 @@
|
||||
<template>
|
||||
<div style="width: 100%;padding-left: 5px;box-sizing: border-box">
|
||||
<a-descriptions style="margin-top: 10px;" title="Info" :column="1" :value-style="{wordBreak:'break-all'}">
|
||||
<a-descriptions style="margin-top: 10px;" :title="$t('util.info')" :column="1" :value-style="{wordBreak:'break-all'}">
|
||||
<template v-if="!item || !item.id">
|
||||
<a-descriptions-item label="name">Desktop</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.name')">Desktop</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Finder_Item_Type.FILE">
|
||||
<a-descriptions-item label="name">{{fileInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<span style="color: blue">
|
||||
File
|
||||
{{$t("util.file")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="size">{{generateSizeFormat(fileInfo?.file.size)}}</a-descriptions-item>
|
||||
<a-descriptions-item label="date">{{moment(fileInfo?.created_time).format("YYYY-MM-DD HH:mm:ss")}}</a-descriptions-item>
|
||||
<a-descriptions-item label="path">
|
||||
<a-descriptions-item :label="$t('util.size')">{{generateSizeFormat(fileInfo?.file.size)}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.date')">{{moment(fileInfo?.created_time).format("YYYY-MM-DD HH:mm:ss")}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.path')">
|
||||
{{generatePathFormat(fileInfo?.parentFolderList)}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Finder_Item_Type.FOLDER">
|
||||
<a-descriptions-item label="name">{{folderInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{folderInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Folder
|
||||
{{$t("util.folder")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="date">{{moment(folderInfo?.created_time).format("YYYY-MM-DD HH:mm:ss")}}</a-descriptions-item>
|
||||
<a-descriptions-item label="path">
|
||||
<a-descriptions-item :label="$t('util.date')">{{moment(folderInfo?.created_time).format("YYYY-MM-DD HH:mm:ss")}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.path')">
|
||||
{{generatePathFormat(folderInfo?.parentFolderList)}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Finder_Item_Type.SHORTCUT">
|
||||
<template v-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.PROJECT">
|
||||
<a-descriptions-item label="name">{{projectInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{projectInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item :label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Project
|
||||
{{$t("util.project")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="key">{{projectInfo?.keyword}}</a-descriptions-item>
|
||||
<a-descriptions-item label="description" v-if="projectInfo?.description">
|
||||
<a-descriptions-item :label="$t('util.key')">{{projectInfo?.keyword}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.description')" v-if="projectInfo?.description">
|
||||
<span style="line-clamp: 4;-webkit-box-orient: vertical;overflow: hidden;display: -webkit-box;-moz-box-orient: vertical;">
|
||||
{{projectInfo?.description}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="create" v-if="projectInfo">
|
||||
<a-descriptions-item :label="$t('util.create')" v-if="projectInfo">
|
||||
<UserAvatar :organization-user-id="projectInfo?.created_by.organizationUserId" :name="projectInfo?.created_by.nickname" :photo="projectInfo?.created_by.photo" :organization-id="projectInfo?.organization_id"></UserAvatar>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.PROJECT_ISSUE">
|
||||
<a-descriptions-item label="name">{{projectIssueInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{projectIssueInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item :label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Project Issue
|
||||
{{$t("util.projectIssue")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="key">{{projectIssueInfo?.project.keyword+"-"+projectIssueInfo?.unique_id}}</a-descriptions-item>
|
||||
<a-descriptions-item label="priority" v-if="projectIssueInfo">
|
||||
<a-descriptions-item :label="$t('util.key')">{{projectIssueInfo?.project.keyword+"-"+projectIssueInfo?.unique_id}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.priority')" v-if="projectIssueInfo">
|
||||
<FieldPriority :priority="projectIssueInfo?.priority"></FieldPriority>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="issue type">
|
||||
<a-descriptions-item :label="$t('util.issueType')">
|
||||
{{projectIssueInfo?.issueType.name}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="status">
|
||||
<a-descriptions-item :label="$t('util.status')">
|
||||
{{projectIssueInfo?.workflowNode.name}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="reporter" v-if="projectIssueInfo?.reporter_id">
|
||||
<a-descriptions-item :label="$t('util.reporter')" v-if="projectIssueInfo?.reporter_id">
|
||||
<UserAvatar :organization-user-id="projectIssueInfo?.reporter_id.organizationUserId" :name="projectIssueInfo?.reporter_id.nickname" :photo="projectIssueInfo?.reporter_id.photo" :organization-id="projectIssueInfo?.project.organization_id"></UserAvatar>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="assigner" v-if="projectIssueInfo?.assigner_id">
|
||||
<a-descriptions-item :label="$t('util.assigner')" v-if="projectIssueInfo?.assigner_id">
|
||||
<UserAvatar :organization-user-id="projectIssueInfo?.assigner_id.organizationUserId" :name="projectIssueInfo?.assigner_id.nickname" :photo="projectIssueInfo?.assigner_id.photo" :organization-id="projectIssueInfo?.project.organization_id"></UserAvatar>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.PROJECT_RELEASE">
|
||||
<a-descriptions-item label="name">{{projectReleaseInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{projectReleaseInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Project Release
|
||||
{{$t("util.projectRelease")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="status">
|
||||
<a-descriptions-item :label="$t('util.status')">
|
||||
{{projectReleaseInfo?.status===ECommon_Model_Project_Release_Status.RELEASE?"Release":projectReleaseInfo?.status===ECommon_Model_Project_Release_Status.ARCHIVED?"Archived":"UnRelease"}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="start">
|
||||
<a-descriptions-item :label="$t('util.start')">
|
||||
{{moment(projectReleaseInfo?.created_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="release">
|
||||
<a-descriptions-item :label="$t('util.release')">
|
||||
{{moment(projectReleaseInfo?.release_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="project">
|
||||
<a-descriptions-item :label="$t('util.project')">
|
||||
{{projectReleaseInfo?.projectName}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.BOARD_SPRINT">
|
||||
<a-descriptions-item label="name">{{sprintInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="issues">{{sprintInfo?.issues.length}}</a-descriptions-item>
|
||||
<a-descriptions-item label="swimLanes">{{sprintInfo?.swimLanes.length}}</a-descriptions-item>
|
||||
<a-descriptions-item label="start">
|
||||
<a-descriptions-item :label="$t('util.name')">{{sprintInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.issues')">{{sprintInfo?.issues.length}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.swimLanes')">{{sprintInfo?.swimLanes.length}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.start')">
|
||||
{{moment(sprintInfo?.start_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="end">
|
||||
<a-descriptions-item :label="$t('util.end')">
|
||||
{{moment(sprintInfo?.end_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="project">
|
||||
<a-descriptions-item :label="$t('util.project')">
|
||||
{{sprintInfo?.project.name}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.WIKI">
|
||||
<a-descriptions-item label="name">{{wikiInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{wikiInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item :label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Wiki Project
|
||||
{{$t("util.wikiProject")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="create" v-if="wikiInfo">
|
||||
<a-descriptions-item :label="$t('util.create')" v-if="wikiInfo">
|
||||
<UserAvatar :organization-user-id="wikiInfo?.created_by.organizationUserId" :name="wikiInfo?.created_by.nickname" :photo="wikiInfo?.created_by.photo" :organization-id="wikiInfo?.organization_id"></UserAvatar>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="wiki count">
|
||||
<a-descriptions-item :label="$t('util.wikiCount')">
|
||||
{{wikiInfo?.data.length}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.WIKI_ITEM">
|
||||
<a-descriptions-item label="name">{{wikiItemInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{wikiItemInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item :label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Wiki Item
|
||||
{{$t("util.wikiItem")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="create" v-if="wikiItemInfo">
|
||||
<a-descriptions-item :label="$t('util.create')" v-if="wikiItemInfo">
|
||||
<UserAvatar :organization-user-id="wikiItemInfo?.created_by.organizationUserId" :name="wikiItemInfo?.created_by.nickname" :photo="wikiItemInfo?.created_by.photo" :organization-id="wikiItemInfo?.wiki.organization_id"></UserAvatar>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="wiki">
|
||||
<a-descriptions-item :label="$t('util.wiki')">
|
||||
{{wikiItemInfo?.wiki.name}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.CALENDAR_EVENT">
|
||||
<a-descriptions-item label="name">{{calendarEventInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{calendarEventInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item :label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Calendar Event
|
||||
{{$t("util.calendarEvent")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="start">
|
||||
<a-descriptions-item :label="$t('util.start')">
|
||||
{{moment(calendarEventInfo?.start_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="end">
|
||||
<a-descriptions-item :label="$t('util.end')">
|
||||
{{moment(calendarEventInfo?.end_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="calendar">
|
||||
<a-descriptions-item :label="$t('util.calendar')">
|
||||
{{calendarEventInfo?.calendarName}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
<template v-else-if="item.shortcut_type===ECommon_Model_Finder_Shortcut_Type.MEETING_ROOM">
|
||||
<a-descriptions-item label="name">{{meetingRoomInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item label="type">
|
||||
<a-descriptions-item :label="$t('util.name')">{{meetingRoomInfo?.name}}</a-descriptions-item>
|
||||
<a-descriptions-item :label="$t('util.type')">
|
||||
<span style="color: blue">
|
||||
Shortcut
|
||||
{{$t("util.shortcut")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="category">
|
||||
<a-descriptions-item :label="$t('util.category')">
|
||||
<span style="color: green">
|
||||
Meeting
|
||||
{{$t("util.meeting")}}
|
||||
</span>
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="start">
|
||||
<a-descriptions-item :label="$t('util.start')">
|
||||
{{moment(meetingRoomInfo?.start_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="end">
|
||||
<a-descriptions-item :label="$t('util.end')">
|
||||
{{moment(meetingRoomInfo?.end_time).format("YYYY-MM-DD HH:mm:ss")}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="organization" v-if="organizationInfo">
|
||||
<a-descriptions-item :label="$t('util.organization')" v-if="organizationInfo">
|
||||
{{organizationInfo.name}}
|
||||
</a-descriptions-item>
|
||||
</template>
|
||||
|
@ -22,7 +22,7 @@
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-row style="flex-direction: column;align-items: center">
|
||||
<a-input size="small" placeholder="type user name" v-model="searchUserKey"></a-input>
|
||||
<a-input size="small" :placeholder="$t('placeholder.typeUserName')" v-model="searchUserKey"></a-input>
|
||||
<a-table style="width: 100%;margin-top: 10px" row-key="id" :columns="columns" :data="teamMemberList.filter(item=>(item.id!==organizationUserId && item.name.includes(searchUserKey)))" :row-selection="rowSelection" v-model:selected-keys="selectKeys" :pagination="false">
|
||||
<template #name="{record}">
|
||||
<UserAvatar :organization-user-id="record.id" :name="record.name" :photo="record.photo"></UserAvatar>
|
||||
@ -130,6 +130,7 @@ import {EClient_EVENTBUS_TYPE, eventBus} from "../../../common/event/event";
|
||||
import {ECommon_Model_Organization_Member_Type} from "../../../../../../common/model/organization";
|
||||
import {TableRowSelection} from "@arco-design/web-vue/es/table/interface";
|
||||
import UserAvatar from "../../../common/component/userAvatar.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const root = ref()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
@ -177,9 +178,10 @@ const rowSelection=ref<TableRowSelection>({
|
||||
showCheckedAll:true,
|
||||
onlyCurrent:false
|
||||
})
|
||||
const {t}=useI18n()
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
title: t("util.name"),
|
||||
slotName: 'name',
|
||||
}
|
||||
]
|
||||
|
@ -43,11 +43,13 @@ import {ECommon_Socket_Type} from "../../../../../../common/socket/types";
|
||||
import {SessionStorage} from "../../../common/storage/session";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {Dialog} from "../../../common/component/dialog/dialog";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const contentRef = ref<HTMLDivElement>()
|
||||
const messageList = ref<IClient_Chat_Message_Item[]>([])
|
||||
const socket=SocketIOClient.get(ECommon_Socket_Type.IM)
|
||||
const {t}=useI18n()
|
||||
let myOrganizationUserId=SessionStorage.get("organizationUserId")
|
||||
const onWheel = (event: WheelEvent) => {
|
||||
let ele = event.currentTarget as HTMLDivElement
|
||||
@ -88,10 +90,10 @@ const getMessageList=async (date?:string)=>{
|
||||
}
|
||||
|
||||
const onFavoriteDelete=async (item:IClient_Chat_Message_Item)=>{
|
||||
let ret=await Dialog.confirm(document.getElementById("imWindow"),appContext,"Do you want delete this favorite?")
|
||||
let ret=await Dialog.confirm(document.getElementById("imWindow"),appContext,t("tip.deleteFavorite"))
|
||||
if(ret) {
|
||||
socket.getSocket().emit("im_favorite_message_delete",item.messageId)
|
||||
Message.info("delete success")
|
||||
Message.info(t("tip.deleteSuccess"))
|
||||
messageList.value.splice(messageList.value.findIndex(obj=>{
|
||||
if(obj.messageId===item.messageId) {
|
||||
return true
|
||||
|
@ -2,8 +2,8 @@
|
||||
<a-layout style="height: 100%" id="imWindow">
|
||||
<a-layout-sider :resize-directions="['right']">
|
||||
<div style="width: 100%;height: 100%;overflow-y: auto;padding: 5px;box-sizing: border-box">
|
||||
<a-select style="width: 100%" placeholder="type user or team" allow-search allow-clear @change="onChange" @search="onSearch">
|
||||
<a-optgroup label="Team" v-if="selectList && selectList.teams && selectList.teams.length>0">
|
||||
<a-select style="width: 100%" :placeholder="$t('placeholder.typeUserOrTeam')" allow-search allow-clear @change="onChange" @search="onSearch">
|
||||
<a-optgroup :label="$t('util.team')" v-if="selectList && selectList.teams && selectList.teams.length>0">
|
||||
<a-option v-for="item in selectList.teams" :value="item.id">
|
||||
<a-row style="align-items: center">
|
||||
<a-avatar :image-url="item.photo" :size="24"></a-avatar>
|
||||
@ -11,7 +11,7 @@
|
||||
</a-row>
|
||||
</a-option>
|
||||
</a-optgroup>
|
||||
<a-optgroup label="User" v-if="selectList && selectList.users && selectList.users.length>0">
|
||||
<a-optgroup :label="$t('util.user')" v-if="selectList && selectList.users && selectList.users.length>0">
|
||||
<a-option v-for="item in selectList.users" :value="item.id">
|
||||
<a-row style="align-items: center">
|
||||
<a-avatar :image-url="item.photo" :size="24"></a-avatar>
|
||||
@ -25,16 +25,16 @@
|
||||
<template #icon>
|
||||
<icon-star></icon-star>
|
||||
</template>
|
||||
Favorites
|
||||
{{$t("controller.app.im.im.favorites")}}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="messages">
|
||||
<template #icon>
|
||||
<icon-search></icon-search>
|
||||
</template>
|
||||
Messages
|
||||
{{$t("controller.app.im.im.messages")}}
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
<a-divider>Recent</a-divider>
|
||||
<a-divider>{{$t("controller.app.im.im.recent")}}</a-divider>
|
||||
<RecentList ref="recentListRef" @select="onSelectChat" :init-data="id?{id,type:chatType}:undefined"></RecentList>
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
@ -42,7 +42,7 @@
|
||||
<Chat :data="messageList" :type="selectedChat.type" :info="selectedChat" @send="onSend" v-if="selectedChat && selectedMenuKeys.length==0" ref="chatRef" @update-more="onShowMore" @click-photo="onClickChatPhoto" @favorite="onFavorite" :is-search="!!locateInfo" :teamMemberList="teamMemberList">
|
||||
<template #info v-if="selectedChat.type===ECommon_IM_Message_EntityType.TEAM">
|
||||
<a-collapse :default-active-key="['members']">
|
||||
<a-collapse-item header="Members" key="members">
|
||||
<a-collapse-item :header="$t('util.members')" key="members">
|
||||
<a-space wrap>
|
||||
<UserAvatar v-for="item in teamMemberList" :organization-user-id="item.id" :name="item.name" :photo="item.photo"></UserAvatar>
|
||||
</a-space>
|
||||
@ -88,11 +88,13 @@ import {ECommon_Content_Line_Config_Type, ICommon_Content_Line} from "../../../.
|
||||
import Favorite from "./favorite.vue";
|
||||
import ImMessageSearch from "./imMessageSearch.vue";
|
||||
import {ICommon_Model_IM_Team_Message} from "../../../../../../common/model/im_team_message";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
id?:string,
|
||||
chatType?:ECommon_IM_Message_EntityType
|
||||
}>()
|
||||
const {t}=useI18n()
|
||||
const recentListRef=ref<InstanceType<typeof RecentList>>()
|
||||
const selectList=ref<ICommon_Route_Res_Organization_FilterUserAndTeam>()
|
||||
const messageList=ref<IClient_Chat_Message_Item[]>([])
|
||||
@ -408,7 +410,7 @@ const onClickFavorite=(key:string)=>{
|
||||
const onFavorite=async (item:IClient_Chat_Message_Item,type: ECommon_IM_Message_EntityType)=>{
|
||||
let myOrganizationUserId=SessionStorage.get("organizationUserId")
|
||||
socket.getSocket().emit("im_favorite_message_add",myOrganizationUserId,type,item.messageId)
|
||||
Message.info("favorite success")
|
||||
Message.info(t("tip.favoriteSuccess"))
|
||||
}
|
||||
|
||||
const handleUserInfo = (id: string, info: {
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div style="height: 100%">
|
||||
<a-row style="width: 100%">
|
||||
<a-input-search placeholder="type your message and at least two characters" v-model="keyword" @search="onSearch" search-button></a-input-search>
|
||||
<a-input-search :placeholder="$t('placeholder.imMessageSearch')" v-model="keyword" @search="onSearch" search-button></a-input-search>
|
||||
</a-row>
|
||||
<a-divider></a-divider>
|
||||
<a-row style="width: 100%;">
|
||||
<a-spin :loading="loading" style="width: 100%;">
|
||||
<a-collapse style="width: 100%" v-model:active-key="activeKeys">
|
||||
<a-collapse-item header="User" key="user">
|
||||
<a-collapse-item :header="$t('util.user')" key="user">
|
||||
<a-collapse style="width: 100%" v-if="userInfoList.length>0" :bordered="false">
|
||||
<a-collapse-item v-for="(value,key) in messageList.users" :key="key">
|
||||
<template #header>
|
||||
@ -42,7 +42,7 @@
|
||||
</a-collapse>
|
||||
<a-empty v-else></a-empty>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="Team" key="team">
|
||||
<a-collapse-item :header="$t('util.team')" key="team">
|
||||
<a-collapse style="width: 100%" v-if="teamInfoList.length>0" :bordered="false">
|
||||
<a-collapse-item v-for="(value,key) in messageList.teams" :key="key">
|
||||
<template #header>
|
||||
|
@ -33,8 +33,8 @@
|
||||
</a-badge>
|
||||
</div>
|
||||
<template #content>
|
||||
<a-doption @click="onProfile(item)">Profile</a-doption>
|
||||
<a-doption @click="onClose(item,index)">Close</a-doption>
|
||||
<a-doption @click="onProfile(item)">{{$t("util.profile")}}</a-doption>
|
||||
<a-doption @click="onClose(item,index)">{{$t("util.close")}}</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-menu-item>
|
||||
|
@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<a-form auto-label-width :model="form" ref="formEle">
|
||||
<a-form-item field="name" label="name" required>
|
||||
<a-form-item field="name" :label="$t('util.name')" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item field="description" label="description">
|
||||
<a-form-item field="description" :label="$t('util.description')">
|
||||
<a-textarea v-model="form.description" allow-clear></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item field="startTime" label="start date" required>
|
||||
<a-form-item field="startTime" :label="$t('util.startDate')" required>
|
||||
<a-date-picker show-time v-model="form.startTime"></a-date-picker>
|
||||
</a-form-item>
|
||||
<a-form-item field="endTime" label="end date" required>
|
||||
<a-form-item field="endTime" :label="$t('util.endDate')" required>
|
||||
<a-date-picker show-time v-model="form.endTime"></a-date-picker>
|
||||
</a-form-item>
|
||||
<a-form-item field="password" label="password" required>
|
||||
<a-form-item field="password" :label="$t('util.password')" required>
|
||||
<a-input v-model="form.password"></a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -4,22 +4,22 @@
|
||||
<a-row style="height: 100%;display: flex;flex-direction: column;justify-content: center;align-items: center">
|
||||
<a-dropdown class="startMeeting" trigger="hover" position="top">
|
||||
<a-button size="large" type="primary" style="width: 300px" status="success" @click="onStartMeeting">
|
||||
Start Meeting
|
||||
{{$t("controller.app.meeting.meeting.startMeeting")}}
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption @click="onPersonalMeetingSetting">Person Meeting Setting</a-doption>
|
||||
<a-doption @click="onPersonalMeetingSetting">{{$t("controller.app.meeting.meeting.personMeetingSetting")}}</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<a-button size="large" type="primary" style="margin-top: 30px;width: 300px" status="warning" @click="onJoinMeeting">Join Meeting</a-button>
|
||||
<a-button size="large" type="primary" style="margin-top: 30px;width: 300px" @click="onScheduleMeeting">Schedule Meeting</a-button>
|
||||
<a-button size="large" type="primary" style="margin-top: 30px;width: 300px" status="warning" @click="onJoinMeeting">{{$t("controller.app.meeting.meeting.joinMeeting")}}</a-button>
|
||||
<a-button size="large" type="primary" style="margin-top: 30px;width: 300px" @click="onScheduleMeeting">{{$t("controller.app.meeting.meeting.scheduleMeeting")}}</a-button>
|
||||
</a-row>
|
||||
</a-layout-content>
|
||||
<a-layout-sider :resize-directions="['left']" :width="300">
|
||||
<a-row style="height: 100%;width: 100%;padding: 5px;box-sizing: border-box">
|
||||
<a-row style="height: 30px;width: 100%;">
|
||||
<a-space>
|
||||
Meeting List:
|
||||
<a-input-search search-button placeholder="type meeting name" size="mini" @search="onSearch" v-model="keyword"></a-input-search>
|
||||
{{$t("controller.app.meeting.meeting.meetingList")}}:
|
||||
<a-input-search search-button :placeholder="$t('placeholder.typeMeetingName')" size="mini" @search="onSearch" v-model="keyword"></a-input-search>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-row style="height: calc(100% - 30px);width: 100%;border-top: 1px solid lightgray;overflow-y: auto;flex-direction: column">
|
||||
@ -40,12 +40,14 @@
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
<template #actions>
|
||||
<icon-video-camera style="color: red" @click="onStartScheduleMeeting(item)"></icon-video-camera>
|
||||
<template v-if="item.type===ECommon_Model_Meeting_Room_Type.SCHEDULE">
|
||||
<icon-edit @click="onEditMeeting(item)"></icon-edit>
|
||||
<icon-delete @click="onDeleteMeeting(item)"></icon-delete>
|
||||
</template>
|
||||
<icon-calendar style="color: cornflowerblue" v-else-if="item.type===ECommon_Model_Meeting_Room_Type.CALENDAR" @click="onCalendarEvent(item)"></icon-calendar>
|
||||
<a-space style="height: 100%">
|
||||
<icon-video-camera style="color: red" @click="onStartScheduleMeeting(item)"></icon-video-camera>
|
||||
<template v-if="item.type===ECommon_Model_Meeting_Room_Type.SCHEDULE">
|
||||
<icon-edit @click="onEditMeeting(item)"></icon-edit>
|
||||
<icon-delete style="color: red" @click="onDeleteMeeting(item)"></icon-delete>
|
||||
</template>
|
||||
<icon-calendar style="color: cornflowerblue" v-else-if="item.type===ECommon_Model_Meeting_Room_Type.CALENDAR" @click="onCalendarEvent(item)"></icon-calendar>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
@ -76,9 +78,9 @@ import MeetingJoinInput from "./meetingJoinInput.vue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../common/event/event";
|
||||
import {useDesktopStore} from "../../desktop/store/desktop";
|
||||
import {ECommon_User_Online_Status} from "../../../../../../common/types";
|
||||
import {ECommon_Model_Finder_Shortcut_Type} from "../../../../../../common/model/finder_item";
|
||||
import {vDrag} from "../../../../teamOS/common/directive/drag";
|
||||
import {ECommon_Model_Organization_Member_Type} from "../../../../../../common/model/organization";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
meetingInitInfo?:{
|
||||
@ -93,6 +95,7 @@ const props=defineProps<{
|
||||
const store=useDesktopStore()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const root=getRootNavigatorRef()
|
||||
const {t}=useI18n()
|
||||
const roomList=ref<DCSType<ICommon_Model_Meeting_Room>[]>([])
|
||||
const pagination=reactive({
|
||||
total:0,
|
||||
@ -147,13 +150,13 @@ const onEditMeeting=async (item:DCSType<ICommon_Model_Meeting_Room>)=>{
|
||||
}
|
||||
|
||||
const onDeleteMeeting=async (item:DCSType<ICommon_Model_Meeting_Room>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this meeting?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteMeeting"))
|
||||
if(ret) {
|
||||
let res=await apiMeeting.deleteRoom({
|
||||
meetingRoomId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
getMeetingList(pagination.current)
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<a-form auto-label-width :model="form" ref="formEle">
|
||||
<a-form-item field="id" label="meeting id" required>
|
||||
<a-form-item field="id" :label="$t('util.meetingId')" required>
|
||||
<a-input v-model="form.id"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item field="password" label="meeting password" required>
|
||||
<a-form-item field="password" :label="$t('util.meetingPassword')" required>
|
||||
<a-input v-model="form.password"></a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -22,7 +22,7 @@
|
||||
</template>
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-descriptions title="Meeting Info" :data="[
|
||||
<a-descriptions :title="$t('controller.app.meeting.meetingOperation.meetingInfo')" :data="[
|
||||
{
|
||||
label:'Meeting Id',
|
||||
value:currentMeeting.id
|
||||
@ -34,9 +34,9 @@
|
||||
]" v-if="currentMeeting"></a-descriptions>
|
||||
<a-divider :margin="10"></a-divider>
|
||||
<a-form :model="form" auto-label-width>
|
||||
<a-form-item field="memberIds" label="Users" required>
|
||||
<a-select style="width: 100%" placeholder="type user or team" multiple allow-search allow-clear v-model="form.memberIds" @search="onSearch">
|
||||
<a-optgroup label="Team" v-if="selectList && selectList.teams && selectList.teams.length>0">
|
||||
<a-form-item field="memberIds" :label="$t('util.users')" required>
|
||||
<a-select style="width: 100%" :placeholder="$t('placeholder.typeUserOrTeam')" multiple allow-search allow-clear v-model="form.memberIds" @search="onSearch">
|
||||
<a-optgroup :label="$t('util.team')" v-if="selectList && selectList.teams && selectList.teams.length>0">
|
||||
<a-option v-for="item in selectList.teams" :value="item.id">
|
||||
<a-row style="align-items: center">
|
||||
<a-avatar :image-url="item.photo" :size="24"></a-avatar>
|
||||
@ -44,7 +44,7 @@
|
||||
</a-row>
|
||||
</a-option>
|
||||
</a-optgroup>
|
||||
<a-optgroup label="User" v-if="selectList && selectList.users && selectList.users.length>0">
|
||||
<a-optgroup :label="$t('util.user')" v-if="selectList && selectList.users && selectList.users.length>0">
|
||||
<a-option v-for="item in selectList.users" :value="item.id">
|
||||
<a-row style="align-items: center">
|
||||
<a-avatar :image-url="item.photo" :size="24"></a-avatar>
|
||||
@ -55,7 +55,7 @@
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button html-type="button" type="primary" @click="onInvite">Invite</a-button>
|
||||
<a-button html-type="button" type="primary" @click="onInvite">{{$t("util.invite")}}</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
@ -69,10 +69,10 @@
|
||||
</a-space>
|
||||
<a-space>
|
||||
<a-button size="mini" type="primary" @click="onLeave">
|
||||
Leave
|
||||
{{$t("util.leave")}}
|
||||
</a-button>
|
||||
<a-button size="mini" type="primary" status="danger" v-if="me?.permission===ECommon_Meeting_Room_Permission.PRESENTER" @click="onEnd">
|
||||
End
|
||||
{{$t("util.end")}}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
@ -92,6 +92,7 @@ import {SocketIOClient} from "../../../common/socket/socket";
|
||||
import {ECommon_Socket_Type} from "../../../../../../common/socket/types";
|
||||
import {ICommon_Route_Res_Organization_FilterUserAndTeam} from "../../../../../../common/routes/response";
|
||||
import {ECommon_Model_Organization_Member_Type} from "../../../../../../common/model/organization";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
me:OrganizationUserItem,
|
||||
@ -107,6 +108,7 @@ const root=getRootNavigatorRef()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const socket=SocketIOClient.getSocket(ECommon_Socket_Type.MEETING).getSocket()
|
||||
let isScreen=ref(false)
|
||||
const {t}=useI18n()
|
||||
props.meetingClient.onScreenStopped=() => {
|
||||
isScreen.value=false
|
||||
}
|
||||
@ -131,7 +133,7 @@ const onToggleVideo=()=>{
|
||||
}
|
||||
|
||||
const onLeave=async ()=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you leave this meeting?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.leaveMeeting"))
|
||||
if(ret) {
|
||||
await props.meetingClient.leave()
|
||||
navigator.pop()
|
||||
@ -139,13 +141,13 @@ const onLeave=async ()=>{
|
||||
}
|
||||
|
||||
const onEnd=async ()=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you end this meeting?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.endMeeting"))
|
||||
if(ret) {
|
||||
let res=await props.meetingClient.end()
|
||||
if(res) {
|
||||
navigator.pop()
|
||||
} else {
|
||||
Message.error("operation failed")
|
||||
Message.error(t("tip.operationFailed"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -179,7 +181,7 @@ const onToggleScreen=async ()=>{
|
||||
if(!isScreen.value) {
|
||||
let ret=await props.meetingClient.startShare()
|
||||
if(ret===false) {
|
||||
Message.error("can't share now")
|
||||
Message.error(t("tip.cannotShare"))
|
||||
} else if(ret===true) {
|
||||
isScreen.value=true
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
</a-button>
|
||||
<a-button size="mini" type="text" v-if="me.permission===ECommon_Meeting_Room_Permission.PRESENTER" @click="onTogglePresenter(item)">
|
||||
<template #icon>
|
||||
<sicon size="15" color="rgb(22, 93, 255)" name="Ant" type="admin" v-if="item.permission===ECommon_Meeting_Room_Permission.PRESENTER" title="presenter"></sicon>
|
||||
<sicon size="15" color="rgb(22, 93, 255)" name="Ant" type="admin" v-if="item.permission===ECommon_Meeting_Room_Permission.PRESENTER" :title="$t('controller.app.meeting.meetingParticipant.presenter')"></sicon>
|
||||
<sicon size="15" color="gray" name="Ant" type="user" v-else></sicon>
|
||||
</template>
|
||||
</a-button>
|
||||
@ -34,7 +34,7 @@
|
||||
<template #actions v-else>
|
||||
<a-button size="mini" type="text" :disabled="true">
|
||||
<template #icon>
|
||||
<sicon size="15" color="rgb(22, 93, 255)" name="Ant" type="admin" v-if="me.permission===ECommon_Meeting_Room_Permission.PRESENTER" title="presenter"></sicon>
|
||||
<sicon size="15" color="rgb(22, 93, 255)" name="Ant" type="admin" v-if="me.permission===ECommon_Meeting_Room_Permission.PRESENTER" :title="$t('controller.app.meeting.meetingParticipant.presenter')"></sicon>
|
||||
<sicon size="15" color="gray" name="Ant" type="user" v-else></sicon>
|
||||
</template>
|
||||
</a-button>
|
||||
@ -54,6 +54,7 @@ import {getCurrentInstance} from "vue";
|
||||
import {MeetingClient} from "../../../common/component/meeting/client";
|
||||
import {SocketIOClient} from "../../../common/socket/socket";
|
||||
import {ECommon_Socket_Type} from "../../../../../../common/socket/types";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
organizationUserList:OrganizationUserItem[],
|
||||
@ -64,9 +65,10 @@ const myOrganizationUserId=SessionStorage.get("organizationUserId")
|
||||
const navigator=getCurrentNavigator()
|
||||
const root=getRootNavigatorRef()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const {t}=useI18n()
|
||||
const socket=SocketIOClient.getSocket(ECommon_Socket_Type.MEETING).getSocket()
|
||||
const onKick=async (item:OrganizationUserItem)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,`Do you want to kick ${item.name}?`)
|
||||
let ret=await Dialog.confirm(root.value,appContext,`${t("tip.kick")}${item.name}?`)
|
||||
if(ret) {
|
||||
props.meetingClient.kick(item.organizationUserId)
|
||||
}
|
||||
@ -74,7 +76,7 @@ const onKick=async (item:OrganizationUserItem)=>{
|
||||
|
||||
const onTogglePresenter=async (item:OrganizationUserItem)=>{
|
||||
let promote=item.permission===ECommon_Meeting_Room_Permission.NORMAL;
|
||||
let ret=await Dialog.confirm(root.value,appContext,`Do you want to ${promote?`promote ${item.name} to presenter`:`demote ${item.name} to normal member`}?`)
|
||||
let ret=await Dialog.confirm(root.value,appContext,`${t("tip.doYouWant")}${promote?`${t("tip.promote")}${item.name}${t("tip.toPresenter")}`:`${t("tip.demote")}${item.name}${t("tip.toNormalMember")}`}?`)
|
||||
if(ret) {
|
||||
if(promote) {
|
||||
let ret=await socket.emitWithAck("meeting_change_presenter",item.organizationUserId,ECommon_Meeting_Room_Permission.PRESENTER)
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="formEle" auto-label-width>
|
||||
<a-form-item field="cameraId" label="select camera">
|
||||
<a-form-item field="cameraId" :label="$t('util.selectCamera')">
|
||||
<div style="width: 80%">
|
||||
<a-select v-model="form.cameraId" placeholder="if you don't choose,we will pick up default">
|
||||
<a-select v-model="form.cameraId" :placeholder="$t('placeholder.meetingPreview')">
|
||||
<a-option v-for="item in cameraList" :value="item.id">{{item.name}}</a-option>
|
||||
</a-select>
|
||||
<div style="width: 100%;margin-top: 10px">
|
||||
@ -10,10 +10,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</a-form-item>
|
||||
<a-form-item field="enableVideo" label="video on">
|
||||
<a-form-item field="enableVideo" :label="$t('util.videoOn')">
|
||||
<a-switch v-model="form.enableVideo"></a-switch>
|
||||
</a-form-item>
|
||||
<a-form-item field="enableAudio" label="audio on">
|
||||
<a-form-item field="enableAudio" :label="$t('util.audioOn')">
|
||||
<a-switch v-model="form.enableAudio"></a-switch>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -41,13 +41,13 @@
|
||||
</a-layout-content>
|
||||
<a-layout-sider :resize-directions="['left']" :width="250" id="meetingRight">
|
||||
<a-tabs size="mini" v-model:active-key="tabValue" style="height: 100%">
|
||||
<a-tab-pane title="participant" key="participant">
|
||||
<a-tab-pane :title="$t('util.participant')" key="participant">
|
||||
<MeetingParticipant :organization-user-list="organizationUserList" :me="me" :meeting-client="meetingClient"></MeetingParticipant>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="chat">
|
||||
<template #title>
|
||||
<a-badge dot :count="unReadCount" :offset="[6,0]">
|
||||
chat
|
||||
{{$t("controller.app.meeting.meetingProfile.chat")}}
|
||||
</a-badge>
|
||||
</template>
|
||||
<MeetingChat :meeting-client="meetingClient" @new-message="onNewMessage" ref="meetingChat"></MeetingChat>
|
||||
|
@ -1,10 +1,10 @@
|
||||
|
||||
<template>
|
||||
<a-form :model="form" auto-label-width ref="formEle">
|
||||
<a-form-item field="id" label="meeting id">
|
||||
<a-form-item field="id" :label="$t('util.meetingId')">
|
||||
{{form.id}}
|
||||
</a-form-item>
|
||||
<a-form-item field="password" label="meeting password" required>
|
||||
<a-form-item field="password" :label="$t('util.meetingPassword')" required>
|
||||
<a-input v-model="form.password"></a-input>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div style="padding: 10px 20px">
|
||||
<a-row>
|
||||
<a-input-search placeholder="please type name" style="width: 400px" v-model="keyword" @search="onSearch"></a-input-search>
|
||||
<a-input-search :placeholder="$t('placeholder.typeName')" style="width: 400px" v-model="keyword" @search="onSearch"></a-input-search>
|
||||
</a-row>
|
||||
<a-space wrap style="margin-top: 20px" size="large">
|
||||
<CardItem v-for="item in userList" :name="item.organizationUser.nickname" :photo="item.user.photo" :description="item.organizationUser.job" @click="showProfile(item.organizationUser)"></CardItem>
|
||||
|
@ -67,7 +67,7 @@
|
||||
</a-layout-sider>
|
||||
<a-layout-content style="padding: 0px 10px">
|
||||
<h3>
|
||||
Recent Teams
|
||||
{{$t("controller.app.people.peopleProfile.recentTeams")}}
|
||||
</h3>
|
||||
<a-list>
|
||||
<a-list-item v-for="item in info.teamList" :key="item.id">
|
||||
@ -78,15 +78,15 @@
|
||||
</a-list-item-meta>
|
||||
<template #actions>
|
||||
<template v-if="organizationUserId===myOrganizationUserId">
|
||||
<a-button type="outline" size="small" @click="onTeamProfile(item.id)">Profile</a-button>
|
||||
<a-button type="outline" size="small" @click="onTeamProfile(item.id)">{{$t("util.profile")}}</a-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-button type="outline" size="small" style="margin-left: 20px" @click="onTeamProfile(item.id)">Profile</a-button>
|
||||
<a-button type="outline" size="small" style="margin-left: 20px" @click="onTeamProfile(item.id)">{{$t("util.profile")}}</a-button>
|
||||
<a-button type="outline" size="small" style="margin-left: 20px;margin-top: 10px" @click="onMessage">
|
||||
<template #icon>
|
||||
<icon-message></icon-message>
|
||||
</template>
|
||||
Message
|
||||
{{$t("util.message")}}
|
||||
</a-button>
|
||||
</template>
|
||||
</template>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm">
|
||||
<a-form-item label="Issue Type" field="issueTypeIds" required>
|
||||
<a-form-item :label="$t('util.issueType')" field="issueTypeIds" required>
|
||||
<a-select v-model="form.issueTypeIds" multiple>
|
||||
<a-option v-for="item in issueTypeList" :value="item.id" :label="item.name"></a-option>
|
||||
</a-select>
|
||||
@ -15,6 +15,7 @@ import {ICommon_Model_Issue_Type} from "../../../../../../../common/model/issue_
|
||||
import {onDialogOk} from "@/business/common/component/dialog/dialog";
|
||||
import {dialogFuncGenerator} from "@/business/common/util/helper";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
boardId:string,
|
||||
@ -22,6 +23,7 @@ const props=defineProps<{
|
||||
const form=reactive({
|
||||
issueTypeIds:[]
|
||||
})
|
||||
const {t}=useI18n()
|
||||
const eleForm=ref(null)
|
||||
const issueTypeList=ref<DCSType<ICommon_Model_Issue_Type>[]>([])
|
||||
|
||||
@ -41,7 +43,7 @@ onBeforeMount(()=>{
|
||||
onDialogOk(dialogFuncGenerator({
|
||||
func:()=>{
|
||||
if(issueTypeList.value.length==0) {
|
||||
Message.error("issue type can not be empty!")
|
||||
Message.error(t("tip.issueTypeCannotBeEmpty"))
|
||||
return false
|
||||
}
|
||||
return Promise.all(issueTypeList.value.map(item=>{
|
||||
|
@ -2,7 +2,7 @@
|
||||
<div style="width: 100%;height: 100%">
|
||||
<a-row style="width: 100%;height: 30px;padding-left: 10px">
|
||||
<a-button type="primary" size="small" @click="onAddColumn">
|
||||
Add Column
|
||||
{{$t("controller.app.project.board.boardConfig.addColumn")}}
|
||||
</a-button>
|
||||
</a-row>
|
||||
<div style="width: 100%;margin-top: 20px;overflow: auto;height: calc(100% - 90px)">
|
||||
@ -40,7 +40,7 @@
|
||||
</template>
|
||||
<template #pinHeader>
|
||||
<a-row style="height: 100%;display: flex;align-items: center;justify-content: space-between;padding: 0 5px;box-sizing: border-box;">
|
||||
<span style="color: grey">Issue Type</span>
|
||||
<span style="color: grey">{{$t("util.issueType")}}</span>
|
||||
<a-space size="mini">
|
||||
<a-button type="text" size="mini" @click="onAddIssueType">
|
||||
<template #icon>
|
||||
@ -88,6 +88,7 @@ import {ICommon_Route_Res_Board_Column_Workflow_Node_Item} from "../../../../../
|
||||
import {Dialog} from "@/business/common/component/dialog/dialog";
|
||||
import {getRootNavigatorRef} from "@/teamOS/common/component/navigator/navigator";
|
||||
import BoardAddIssueType from "@/business/controller/app/project/board/boardAddIssueType.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
boardId:string
|
||||
@ -95,6 +96,7 @@ const props=defineProps<{
|
||||
const root=getRootNavigatorRef()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const issueTypeList=ref<DCSType<ICommon_Model_Issue_Type>[]>([])
|
||||
const {t}=useI18n()
|
||||
const workflowUnSetNodeMap=ref<{
|
||||
[issueTypeId:string]:ICommon_Model_Workflow_Node[]
|
||||
}>()
|
||||
@ -317,7 +319,7 @@ const onColumnChange=async (id:string,index:number)=>{
|
||||
}
|
||||
|
||||
const onEditColumn=async (id:string,name:string)=>{
|
||||
let ret=await Dialog.input(root.value,appContext,"Edit Column Name",name)
|
||||
let ret=await Dialog.input(root.value,appContext,t("tip.editColumnName"),name)
|
||||
if(ret) {
|
||||
let res=await apiBoard.editColumn({
|
||||
boardColumnId:id,
|
||||
@ -332,7 +334,7 @@ const onEditColumn=async (id:string,name:string)=>{
|
||||
}
|
||||
|
||||
const onDeleteColumn=async (id:string)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete column?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteColumn"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.deleteColumn({
|
||||
boardColumnId:id
|
||||
@ -349,7 +351,7 @@ const onDeleteColumn=async (id:string)=>{
|
||||
}
|
||||
|
||||
const onAddColumn=async ()=>{
|
||||
let ret=await Dialog.input(root.value,appContext,"New Column Title")
|
||||
let ret=await Dialog.input(root.value,appContext,t("tip.newColumnTitle"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.addColumn({
|
||||
name:ret,
|
||||
@ -367,7 +369,7 @@ const onAddColumn=async ()=>{
|
||||
}
|
||||
|
||||
const onDeleteIssueType=async (item:DCSType<ICommon_Model_Issue_Type>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this issue type?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.removeIssueType"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.unbindIssueType({
|
||||
boardId:props.boardId,
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm">
|
||||
<a-form-item label="name" field="name" required>
|
||||
<a-form-item :label="$t('util.name')" field="name" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="description" field="description">
|
||||
<a-form-item :label="$t('util.description')" field="description">
|
||||
<a-textarea v-model="form.description" allow-clear></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label="Issue Type" field="issueTypeIds" v-if="type=='add'">
|
||||
<a-form-item :label="$t('util.issueType')" field="issueTypeIds" v-if="type=='add'">
|
||||
<a-select v-model="form.issueTypeIds" multiple>
|
||||
<a-option v-for="item in issueTypeList" :value="item.id" :label="item.name"></a-option>
|
||||
</a-select>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div style="padding: 0 10px">
|
||||
<a-form :model="form" ref="eleForm" auto-label-width>
|
||||
<a-form-item label="Action" field="actionId" required>
|
||||
<a-form-item :label="$t('util.action')" field="actionId" required>
|
||||
<a-select v-model="form.actionId" @change="onChange">
|
||||
<a-option v-for="item in workflowActionList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-divider orientation="left" v-if="valueList.length>0">
|
||||
Fields
|
||||
{{$t("util.fields")}}
|
||||
</a-divider>
|
||||
<a-form-item v-for="value in valueList" :key="value.field.id" :label="value.field.name" :extra="value.field.description" :field="value.field.name" :required="!value.field.optional">
|
||||
<FieldInput :item="value" :project-id="projectId"></FieldInput>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<a-option v-for="item in sprintList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
<a-button type="primary" size="small" @click="onGo">
|
||||
Go
|
||||
{{$t("util.go")}}
|
||||
</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
@ -61,9 +61,9 @@
|
||||
<template #pinHeader>
|
||||
<a-row style="height: 100%;display: flex;align-items: center;justify-content: space-between;padding: 0 5px;box-sizing: border-box;">
|
||||
<a-space>
|
||||
<span style="color: grey">Swim Lane</span>
|
||||
<span style="color: grey">{{$t("util.swimLane")}}</span>
|
||||
<span :style="{color: sprintInfo.status!==ECommon_Model_Board_Sprint_Status.COMPLETED?'dodgerblue':'rgb(0,180,42)'}">
|
||||
({{sprintInfo.status===ECommon_Model_Board_Sprint_Status.NOTSTART?"Not Start":sprintInfo.status===ECommon_Model_Board_Sprint_Status.STARTING?"Starting":"Completed"}})
|
||||
({{sprintInfo.status===ECommon_Model_Board_Sprint_Status.NOTSTART?$t("util.notStart"):sprintInfo.status===ECommon_Model_Board_Sprint_Status.STARTING?$t("util.starting"):$t("util.completed")}})
|
||||
</span>
|
||||
</a-space>
|
||||
<a-button size="mini" type="text" @click="onAddSwimLane" v-if="sprintInfo.status!==ECommon_Model_Board_Sprint_Status.COMPLETED">
|
||||
@ -143,6 +143,7 @@ import ProjectIssueNext from "@/business/controller/app/project/issue/projectIss
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "@/business/common/event/event";
|
||||
import {ECommon_Model_Workflow_Node_Status} from "../../../../../../../common/model/workflow_node";
|
||||
import {ECommon_Model_Project_Issue_Approval_Type} from "../../../../../../../common/model/project_issue_approval";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
moment;
|
||||
const props=defineProps<{
|
||||
@ -154,6 +155,7 @@ const appContext=getCurrentInstance().appContext
|
||||
const sprintId=ref("")
|
||||
const sprintList=ref<DCSType<ICommon_Model_Board_Sprint>[]>([])
|
||||
const sprintInfo=ref<DCSType<ICommon_Route_Res_Board_Sprint_Info>>()
|
||||
const {t}=useI18n()
|
||||
const cardData=ref<{
|
||||
id:string,
|
||||
name:string,
|
||||
@ -196,7 +198,7 @@ const onSearch=async (keyword:string)=>{
|
||||
|
||||
const onGo=async ()=>{
|
||||
if(!sprintId.value) {
|
||||
Message.error("you should select a sprint!")
|
||||
Message.error(t("tip.selectSprint"))
|
||||
return
|
||||
}
|
||||
let [resSprintInfo,resListColumn]=await Promise.all([
|
||||
@ -331,7 +333,7 @@ const onEditSwimLane=async (item:DCSType<ICommon_Model_Board_Sprint_SwimLane>)=>
|
||||
}
|
||||
|
||||
const onDeleteSwimLane=async (item:DCSType<ICommon_Model_Board_Sprint_SwimLane>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this swim lane?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteSwimLane"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.deleteSwimLane({
|
||||
boardSprintSwimLaneId:item.id
|
||||
@ -457,7 +459,7 @@ const onDrop=async (item:DCSType<ICommon_Model_Board_Sprint_SwimLane>,columnId:s
|
||||
}
|
||||
}
|
||||
} else if(nextActionList.length==0) {
|
||||
Message.error("this issue can not move to this column!")
|
||||
Message.error(t("tip.notMoveToColumn"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -520,7 +522,7 @@ const onAction=async (projectIssueId:string,item:ICommon_Model_Workflow_Action |
|
||||
return
|
||||
}
|
||||
} else if(item.name==="Reject") {
|
||||
let ret=await Dialog.inputRich(root.value,appContext,"Reject Reason")
|
||||
let ret=await Dialog.inputRich(root.value,appContext,t("tip.rejectReason"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.rejectApproval({
|
||||
projectIssueId:projectIssueId,
|
||||
|
@ -2,8 +2,8 @@
|
||||
<div>
|
||||
<a-row>
|
||||
<a-space wrap>
|
||||
<a-input-search v-model="keyword" placeholder="please type board name" style="width: 250px" @search="onSearch"></a-input-search>
|
||||
<a-button type="primary" @click="onCreate" v-if="checkPermission(permission,Permission_Types.Project.EDIT)">Create</a-button>
|
||||
<a-input-search v-model="keyword" :placeholder="$t('placeholder.typeBoardName')" style="width: 250px" @search="onSearch"></a-input-search>
|
||||
<a-button type="primary" @click="onCreate" v-if="checkPermission(permission,Permission_Types.Project.EDIT)">{{$t("util.create")}}</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-table style="margin-top: 10px" :columns="columns" :data="boardList" :pagination="pagination" @pageChange="onPageChange">
|
||||
@ -15,8 +15,8 @@
|
||||
</template>
|
||||
<template #operation="{record}">
|
||||
<a-space v-if="checkPermission(permission,Permission_Types.Project.EDIT)" wrap>
|
||||
<a-button size="small" @click="onEdit(record)">Edit</a-button>
|
||||
<a-button size="small" status="danger" @click="onDelete(record)">Delete</a-button>
|
||||
<a-button size="small" @click="onEdit(record)">{{$t("util.edit")}}</a-button>
|
||||
<a-button size="small" status="danger" @click="onDelete(record)">{{$t("util.delete")}}</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-table>
|
||||
@ -38,22 +38,24 @@ import {
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {ICommon_Model_Board} from "../../../../../../../common/model/board";
|
||||
import BoardEdit from "@/business/controller/app/project/board/boardEdit.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const objInject=inject(injectProjectInfo)
|
||||
const projectId=objInject.id
|
||||
const permission=objInject.permission
|
||||
const key=objInject.key
|
||||
const {t}=useI18n()
|
||||
const columns=[
|
||||
{
|
||||
title:"Name",
|
||||
title:t("util.name"),
|
||||
slotName:"name"
|
||||
},
|
||||
{
|
||||
title:"Description",
|
||||
title:t("util.description"),
|
||||
slotName: "description"
|
||||
},
|
||||
{
|
||||
title:"Operation",
|
||||
title:t("util.operation"),
|
||||
slotName: "operation"
|
||||
}
|
||||
]
|
||||
@ -106,13 +108,13 @@ const onEdit=async (item:DCSType<ICommon_Model_Board>)=>{
|
||||
}
|
||||
}
|
||||
const onDelete=async (item:DCSType<ICommon_Model_Board>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this board?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteBoard"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.deleteBoard({
|
||||
boardId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
search(pagination.current)
|
||||
}
|
||||
}
|
||||
|
@ -3,20 +3,20 @@
|
||||
<a-row style="width: 100%;font-size: 30px;align-items: center;justify-content: space-between;padding: 0px 10px;box-sizing: border-box;height: 35px">
|
||||
{{info?.name}}
|
||||
<a-button type="primary" size="small" @click="onEdit">
|
||||
Edit
|
||||
{{$t("util.edit")}}
|
||||
</a-button>
|
||||
</a-row>
|
||||
<a-row style="width: 100%;margin-top: 20px;padding:0px 10px;box-sizing: border-box;height: 20px">
|
||||
{{info?.description}}
|
||||
</a-row>
|
||||
<a-tabs style="width: 100%;margin-top: 20px;height: calc(100% - 95px);" @scroll="$event.currentTarget.scrollTop=0" :default-active-key="boardSprintId?'kanban':'sprint'">
|
||||
<a-tab-pane key="sprint" title="Sprint">
|
||||
<a-tab-pane key="sprint" :title="$t('util.sprint')">
|
||||
<BoardSprintList :board-id="boardId"></BoardSprintList>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="kanban" title="Kanban">
|
||||
<a-tab-pane key="kanban" :title="$t('util.kanban')">
|
||||
<BoardKanban :board-id="boardId" :board-sprint-id="boardSprintId"></BoardKanban>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="config" title="Config">
|
||||
<a-tab-pane key="config" :title="$t('util.config')">
|
||||
<BoardConfig :board-id="boardId"></BoardConfig>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm" auto-label-width>
|
||||
<a-form-item label="Issue Types">
|
||||
<a-form-item :label="$t('util.issueTypes')">
|
||||
<a-space>
|
||||
<a-tag v-for="item in issueTypeList">
|
||||
{{item.name}}
|
||||
</a-tag>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
<a-form-item field="issues" label="Issues" required>
|
||||
<a-form-item field="issues" :label="$t('util.issues')" required>
|
||||
<a-select multiple allow-search v-model="form.issues" @search="onSearch">
|
||||
<a-option v-for="item in issueList" :value="item.id">
|
||||
{{item.project.keyword}}-{{item.unique_id}} {{item.name}}
|
||||
@ -25,6 +25,7 @@ import {ICommon_Route_Res_Project_Issue_filter_Item} from "../../../../../../../
|
||||
import {onDialogOk} from "@/business/common/component/dialog/dialog";
|
||||
import {dialogFuncGenerator} from "@/business/common/util/helper";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
boardSprintId:string,
|
||||
@ -35,6 +36,7 @@ const form=reactive({
|
||||
issues:[]
|
||||
})
|
||||
const eleForm=ref()
|
||||
const {t}=useI18n()
|
||||
const issueTypeList=ref<DCSType<ICommon_Model_Issue_Type>[]>([])
|
||||
const issueList=ref<DCSType<ICommon_Route_Res_Project_Issue_filter_Item>[]>([])
|
||||
const getIssueTypeList=async ()=>{
|
||||
@ -69,7 +71,7 @@ onDialogOk(dialogFuncGenerator({
|
||||
},
|
||||
func:()=>{
|
||||
if(form.issues.length==0) {
|
||||
Message.error("issue should not be empty")
|
||||
Message.error(t("tip.issueShouldNotBeEmpty"))
|
||||
return false
|
||||
}
|
||||
return apiBoard.addSprintIssues({
|
||||
|
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm">
|
||||
<a-form-item label="name" field="name" required>
|
||||
<a-form-item :label="$t('util.name')" field="name" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="dateRange" field="dateRange" required>
|
||||
<a-range-picker v-model="form.dateRange" :placeholder="['Start Date','End Date']"></a-range-picker>
|
||||
<a-form-item :label="$t('util.dateRange')" field="dateRange" required>
|
||||
<a-range-picker v-model="form.dateRange" :placeholder="[$t('util.startDate'),$t('util.endDate')]"></a-range-picker>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
@ -2,14 +2,14 @@
|
||||
<div>
|
||||
<a-row style="width: 100%;">
|
||||
<a-space>
|
||||
Status:
|
||||
{{$t("util.status")}}:
|
||||
<a-select size="small" style="width: 100px;" v-model="status">
|
||||
<a-option :value="-1">All</a-option>
|
||||
<a-option :value="ECommon_Model_Board_Sprint_Status.NOTSTART">Not Start</a-option>
|
||||
<a-option :value="ECommon_Model_Board_Sprint_Status.STARTING">Starting</a-option>
|
||||
<a-option :value="ECommon_Model_Board_Sprint_Status.COMPLETED">Completed</a-option>
|
||||
<a-option :value="-1">{{$t("util.all")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Board_Sprint_Status.NOTSTART">{{$t("controller.app.project.board.boardSprintList.notStart")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Board_Sprint_Status.STARTING">{{$t("controller.app.project.board.boardSprintList.starting")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Board_Sprint_Status.COMPLETED">{{$t("controller.app.project.board.boardSprintList.completed")}}</a-option>
|
||||
</a-select>
|
||||
<a-input-search size="small" style="width: 300px" v-model="keyword" @search="onSearch" search-button placeholder="please type sprint name"></a-input-search>
|
||||
<a-input-search size="small" style="width: 300px" v-model="keyword" @search="onSearch" search-button :placeholder="$t('placeholder.typeSprintName')"></a-input-search>
|
||||
<a-button size="small" type="primary" @click="onCreate">
|
||||
Create
|
||||
</a-button>
|
||||
@ -33,10 +33,10 @@
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-doption size="mini" type="primary" status="success" @click="onStartSprint(item,$event)" v-if="item.status!==ECommon_Model_Board_Sprint_Status.STARTING">
|
||||
Start
|
||||
{{$t("util.start")}}
|
||||
</a-doption>
|
||||
<a-doption size="mini" type="outline" status="success" @click="onCompleteSprint(item,$event)" v-else>
|
||||
Complete
|
||||
{{$t("util.complete")}}
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
@ -96,6 +96,7 @@ import {injectProjectInfo} from "@/business/common/util/symbol";
|
||||
import BoardSprintAddIssue from "@/business/controller/app/project/board/boardSprintAddIssue.vue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "@/business/common/event/event";
|
||||
import FieldPriority from "@/business/common/component/field/fieldPriority.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
boardId:string
|
||||
@ -115,6 +116,7 @@ const loading=ref(false)
|
||||
const objInject=inject(injectProjectInfo)
|
||||
const projectId=objInject.id
|
||||
const key=objInject.key
|
||||
const {t}=useI18n()
|
||||
const search=async (page:number)=>{
|
||||
let res=await apiBoard.listSprint({
|
||||
boardId:props.boardId,
|
||||
@ -193,7 +195,7 @@ const onEdit=async (item:DCSType<ICommon_Model_Board_Sprint>,event:MouseEvent)=>
|
||||
|
||||
const onDelete=async (item:DCSType<ICommon_Model_Board_Sprint>,event:MouseEvent)=>{
|
||||
event.stopPropagation()
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this sprint?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteSprint"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.deleteSprint({
|
||||
boardSprintId:item.id
|
||||
@ -206,7 +208,7 @@ const onDelete=async (item:DCSType<ICommon_Model_Board_Sprint>,event:MouseEvent)
|
||||
|
||||
const onStartSprint=async (item:DCSType<ICommon_Model_Board_Sprint>,event:MouseEvent)=>{
|
||||
event.stopPropagation()
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to start this sprint?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.startSprint"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.startSprint({
|
||||
boardSprintId:item.id
|
||||
@ -219,7 +221,7 @@ const onStartSprint=async (item:DCSType<ICommon_Model_Board_Sprint>,event:MouseE
|
||||
|
||||
const onCompleteSprint=async (item:DCSType<ICommon_Model_Board_Sprint>,event:MouseEvent)=>{
|
||||
event.stopPropagation()
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to complete this sprint?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.completeSprint"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.completeSprint({
|
||||
boardSprintId:item.id
|
||||
@ -231,7 +233,7 @@ const onCompleteSprint=async (item:DCSType<ICommon_Model_Board_Sprint>,event:Mou
|
||||
}
|
||||
|
||||
const onRemoveIssue=async (issue:DCSType<ICommon_Route_Res_Board_Sprint_Issue_Item>,sprint:DCSType<ICommon_Model_Board_Sprint>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to remove this issue from this sprint?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.removeIssueFromSprint"))
|
||||
if(ret) {
|
||||
let res=await apiBoard.removeProjectIssue({
|
||||
projectIssueId:issue.id
|
||||
|
@ -6,7 +6,7 @@
|
||||
<a-row style="width: 100%;align-items: center">
|
||||
{{info?.name}}
|
||||
<span :style="{color: info?.status!==ECommon_Model_Board_Sprint_Status.COMPLETED?'dodgerblue':'rgb(0,180,42)'}">
|
||||
{{info?.status===ECommon_Model_Board_Sprint_Status.NOTSTART?"Not Start":info?.status===ECommon_Model_Board_Sprint_Status.STARTING?"Starting":"Completed"}}
|
||||
{{info?.status===ECommon_Model_Board_Sprint_Status.NOTSTART?$t("controller.app.project.board.boardSprintList.notStart"):info?.status===ECommon_Model_Board_Sprint_Status.STARTING?$t("controller.app.project.board.boardSprintList.starting"):$t("controller.app.project.board.boardSprintList.completed")}}
|
||||
</span>
|
||||
</a-row>
|
||||
<a-row style="margin-top: 15px;">
|
||||
@ -21,13 +21,13 @@
|
||||
<a-row style="width: 100%;margin-top: 15px;justify-content: space-between;align-items: center">
|
||||
<a-space style="color: dodgerblue">
|
||||
<span>
|
||||
Swim Lanes:{{info?.swimLanes.length}}
|
||||
{{$t("controller.app.project.board.boardSprintList.swimLanes")}}:{{info?.swimLanes.length}}
|
||||
</span>
|
||||
<span>
|
||||
Issues:{{info?.issues.length}}
|
||||
{{$t("util.issues")}}:{{info?.issues.length}}
|
||||
</span>
|
||||
</a-space>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @click="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @click="onProfile">{{$t("util.profile")}}</a-button>
|
||||
</a-row>
|
||||
</a-row>
|
||||
</template>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm" auto-label-width>
|
||||
<a-form-item field="issues" label="Issues" required>
|
||||
<a-form-item field="issues" :label="$t('util.issues')" required>
|
||||
<a-select multiple allow-search v-model="form.issues" @search="onSearch">
|
||||
<a-optgroup v-for="(_,swimLaneName) in optionMap" :label="swimLaneName">
|
||||
<a-option v-for="item in optionMap[swimLaneName]" :value="item.id" :label="props.projectKey+'-'+item.unique_id">
|
||||
@ -23,6 +23,7 @@ import {ICommon_Route_Res_Board_Sprint_Issue_Item} from "../../../../../../../co
|
||||
import {onDialogOk} from "@/business/common/component/dialog/dialog";
|
||||
import {dialogFuncGenerator} from "@/business/common/util/helper";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
boardSprintSwimLaneId:string,
|
||||
@ -34,6 +35,7 @@ const form=reactive({
|
||||
issues:[]
|
||||
})
|
||||
const eleForm=ref()
|
||||
const {t}=useI18n()
|
||||
const issueMap=ref<{
|
||||
[swimLaneName:string]:DCSType<ICommon_Route_Res_Board_Sprint_Issue_Item>[]
|
||||
}>()
|
||||
@ -87,7 +89,7 @@ onDialogOk(dialogFuncGenerator({
|
||||
},
|
||||
func:()=>{
|
||||
if(form.issues.length==0) {
|
||||
Message.error("issue should not be empty")
|
||||
Message.error(t("tip.issueShouldNotBeEmpty"))
|
||||
return false
|
||||
}
|
||||
return Promise.all(form.issues.map(item=>{
|
||||
|
@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm">
|
||||
<a-form-item label="name" field="name" required>
|
||||
<a-form-item :label="$t('util.name')" field="name" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="priority" field="priority" required>
|
||||
<a-form-item :label="$t('util.priority')" field="priority" required>
|
||||
<a-select v-model="form.priority">
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.LOW">Low</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.MEDIUM">MEDIUM</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.HIGH">HIGH</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.URGENT">URGENT</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.LOW">{{$t("util.low")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.MEDIUM">{{$t("util.medium")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.HIGH">{{$t("util.high")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.URGENT">{{$t("util.urgent")}}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -26,16 +26,16 @@
|
||||
<template #split>
|
||||
|
|
||||
</template>
|
||||
<a-statistic title="Issue Total" :value="staticInfo?.issueCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.project.home.projectHome.issueTotal')" :value="staticInfo?.issueCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="UnResolved Issue Total" :value="staticInfo?.issueUnDoneCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.project.home.projectHome.unResolvedIssueTotal')" :value="staticInfo?.issueUnDoneCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="Release Total" :value="staticInfo?.releaseCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.project.home.projectHome.releaseTotal')" :value="staticInfo?.releaseCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="Sprint Total" :value="staticInfo?.sprintCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.project.home.projectHome.sprintTotal')" :value="staticInfo?.sprintCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
</a-space>
|
||||
@ -105,6 +105,7 @@ import FieldPriority from "@/business/common/component/field/fieldPriority.vue";
|
||||
import {ICommon_Model_Project_Issue} from "../../../../../../../common/model/project_issue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "@/business/common/event/event";
|
||||
import {ICommon_Model_Project_Release} from "../../../../../../../common/model/project_release";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
echarts.use([
|
||||
TitleComponent,
|
||||
@ -123,30 +124,31 @@ let userIssueListChart:EChartsType,userUnDoneIssueChart:EChartsType
|
||||
const projectId=inject(injectProjectInfo).id
|
||||
const key=inject(injectProjectInfo).key
|
||||
const permission=inject(injectProjectInfo).permission
|
||||
const {t}=useI18n()
|
||||
const data = [
|
||||
{
|
||||
id: "statics",
|
||||
name: "Statics",
|
||||
name: t("controller.app.project.home.projectHome.statics"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "myRecentIssueList",
|
||||
name: "My Recent Working Issue List",
|
||||
name: t("controller.app.project.home.projectHome.myRecentIssueList"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "userIssueList",
|
||||
name: "Users' Issue Chart",
|
||||
name: t("controller.app.project.home.projectHome.userIssueList"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "userUnDoneIssueList",
|
||||
name: "User's UnResolved Issue Chart",
|
||||
name: t("controller.app.project.home.projectHome.userUnDoneIssueList"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "recentReleaseList",
|
||||
name: "Recent Release List",
|
||||
name: t("controller.app.project.home.projectHome.recentReleaseList"),
|
||||
data: null
|
||||
},
|
||||
]
|
||||
@ -174,6 +176,9 @@ const getProjectInfo=async ()=>{
|
||||
const initCharts=()=>{
|
||||
userIssueListChart=echarts.init(userIssueListEle.value)
|
||||
userIssueListChart.setOption({
|
||||
grid:{
|
||||
left:60
|
||||
},
|
||||
dataset:{
|
||||
source:[
|
||||
["count","name"],
|
||||
@ -189,7 +194,12 @@ const initCharts=()=>{
|
||||
},
|
||||
yAxis: {
|
||||
name:"User",
|
||||
type: 'category'
|
||||
type: 'category',
|
||||
axisLabel:{
|
||||
show:true,
|
||||
overflow:"breakAll",
|
||||
width:40
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@ -204,6 +214,9 @@ const initCharts=()=>{
|
||||
})
|
||||
userUnDoneIssueChart=echarts.init(userUnDoneIssueEle.value)
|
||||
userUnDoneIssueChart.setOption({
|
||||
grid:{
|
||||
left:60
|
||||
},
|
||||
dataset:{
|
||||
source:[
|
||||
["count","name"],
|
||||
@ -219,7 +232,12 @@ const initCharts=()=>{
|
||||
},
|
||||
yAxis: {
|
||||
name:"User",
|
||||
type: 'category'
|
||||
type: 'category',
|
||||
axisLabel:{
|
||||
show:true,
|
||||
overflow:"breakAll",
|
||||
width:40
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm">
|
||||
<a-form-item label="issue" field="issueId" required>
|
||||
<a-form-item :label="$t('util.issue')" field="issueId" required>
|
||||
<a-select allow-clear allow-search @search="onSearch" v-model="form.issueId">
|
||||
<a-option v-for="item in issueList" :label="item.name" :value="item.id">
|
||||
{{projectKey+"-"+item.unique_id+" "+item.name}}
|
||||
@ -25,7 +25,7 @@ const eleForm=ref(null)
|
||||
const form=reactive({
|
||||
issueId:""
|
||||
})
|
||||
const issueList=ref<DCSType<ICommon_Route_Res_Project_Issue_filter_Item[]>>([])
|
||||
const issueList=ref<DCSType<ICommon_Route_Res_Project_Issue_filter_Item>[]>([])
|
||||
const onSearch=async (keyword:string)=>{
|
||||
let res=await apiIssue.filter({
|
||||
name:keyword,
|
||||
|
@ -7,7 +7,7 @@
|
||||
</a-spin>
|
||||
</template>
|
||||
<template #actions>
|
||||
<a-button type="primary" size="small" @click="onCommentAdd" style="margin-top: 10px">Save</a-button>
|
||||
<a-button type="primary" size="small" @click="onCommentAdd" style="margin-top: 10px">{{$t("util.save")}}</a-button>
|
||||
</template>
|
||||
</a-comment>
|
||||
<a-comment v-for="(item,index) in commentList" :author="item.value.created_by.nickname" :datetime="moment(item.value.created_time).format('YYYY-MM-DD HH:mm:ss')">
|
||||
@ -71,6 +71,7 @@ import RichEditor from "../../../../common/component/richEditor/richEditor.vue";
|
||||
import {RichEditorEventHandle} from "../../../../common/component/richEditorEventHandle";
|
||||
import {DropParam, vDrop} from "../../../../../teamOS/common/directive/drop";
|
||||
import UserAvatar from "../../../../common/component/userAvatar.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectIssueId:string
|
||||
@ -89,6 +90,7 @@ const objEditor=ref<InstanceType<typeof RichEditor>>()
|
||||
const objEditorAdd=ref<InstanceType<typeof RichEditor>>()
|
||||
const loading=ref(false)
|
||||
const popMenuList=ref(RichEditorEventHandle.popMenuList)
|
||||
const {t}=useI18n()
|
||||
const getCommentList=async ()=>{
|
||||
let res=await apiIssue.commentList({
|
||||
projectIssueId:props.projectIssueId
|
||||
@ -133,7 +135,7 @@ const onSave=async (item:DCSType<{
|
||||
}
|
||||
}))
|
||||
if(value.length==0) {
|
||||
Message.error("content can not be empty")
|
||||
Message.error(t("tip.contentNotEmpty"))
|
||||
return
|
||||
}
|
||||
let res=await apiIssue.commentEdit({
|
||||
@ -147,7 +149,7 @@ const onSave=async (item:DCSType<{
|
||||
}
|
||||
const onRemoveComment=async (index:number)=>{
|
||||
let item=commentList.value[index];
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this comment?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteComment"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.commentRemove({
|
||||
contentId:item.value.id
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div style="padding: 0 10px">
|
||||
<a-form layout="vertical" :model="form" ref="eleForm">
|
||||
<a-form-item label="Issue Type" field="issueTypeId" required>
|
||||
<a-form-item :label="$t('util.issueType')" field="issueTypeId" required>
|
||||
<a-select v-model="form.issueTypeId" @change="onIssueTypeChange">
|
||||
<a-option v-for="item in issueTypeList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-divider orientation="left" v-if="valueList.length>0">Convert Fields</a-divider>
|
||||
<a-divider orientation="left" v-if="valueList.length>0">{{$t("controller.app.project.issue.projectIssueConvert.convertFields")}}</a-divider>
|
||||
<a-form-item v-for="value in valueList" :key="value.field.id" :extra="value.field.description" :field="value.field.name" :required="!value.field.optional">
|
||||
<template #label>
|
||||
{{value.field.name}}
|
||||
@ -18,7 +18,7 @@
|
||||
<a-list-item v-for="item in originValueList.filter(item=>item.nodeField.fieldType.type===value.fieldType.type)" :key="item.issueFieldValue.id">
|
||||
{{item.nodeField.field.name}}
|
||||
<template #actions>
|
||||
<a-button type="primary" size="mini" @click="onImport(item,value)">Import</a-button>
|
||||
<a-button type="primary" size="mini" @click="onImport(item,value)">{{$t("util.import")}}</a-button>
|
||||
</template>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
|
@ -1,26 +1,26 @@
|
||||
<template>
|
||||
<div style="padding: 0 10px">
|
||||
<a-form layout="vertical" :model="form" ref="eleForm">
|
||||
<a-form-item label="Issue Type" field="issueTypeId" required>
|
||||
<a-form-item :label="$t('util.issueType')" field="issueTypeId" required>
|
||||
<a-select v-model="form.issueTypeId" @change="onIssueTypeChange">
|
||||
<a-option v-for="item in issueTypeList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="name" field="name" required>
|
||||
<a-form-item :label="$t('util.name')" field="name" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="description" field="description">
|
||||
<a-form-item :label="$t('util.description')" field="description">
|
||||
<a-textarea v-model="form.description"></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label="priority" field="priority" required>
|
||||
<a-form-item :label="$t('util.priority')" field="priority" required>
|
||||
<a-select v-model="form.priority">
|
||||
<a-option label="low" :value="ECommon_Model_Project_Issue_Priority.LOW"></a-option>
|
||||
<a-option label="medium" :value="ECommon_Model_Project_Issue_Priority.MEDIUM"></a-option>
|
||||
<a-option label="high" :value="ECommon_Model_Project_Issue_Priority.HIGH"></a-option>
|
||||
<a-option label="urgent" :value="ECommon_Model_Project_Issue_Priority.URGENT"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.LOW">{{$t('util.low')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.MEDIUM">{{$t('util.medium')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.HIGH">{{$t('util.high')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.URGENT">{{$t('util.urgent')}}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="assigner">
|
||||
<a-form-item :label="$t('util.assigner')">
|
||||
<a-select allow-search @search="onSearchAssigner" v-model="form.assigner">
|
||||
<a-option v-for="item in assignerList" :label="item.organizationUser.nickname" :value="item.organizationUser.id">
|
||||
<a-avatar :size="24" :image-url="item.user.photo"></a-avatar>
|
||||
@ -28,7 +28,7 @@
|
||||
</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="reporter">
|
||||
<a-form-item :label="$t('util.reporter')">
|
||||
<a-select allow-search @search="onSearchReporter" v-model="form.reporter">
|
||||
<a-option v-for="item in reporterList" :label="item.organizationUser.nickname" :value="item.organizationUser.id">
|
||||
<a-avatar :size="24" :image-url="item.user.photo"></a-avatar>
|
||||
|
@ -1,35 +1,35 @@
|
||||
<template>
|
||||
<div class="issueProfileDetail">
|
||||
<a-collapse :default-active-key="['detail']">
|
||||
<a-collapse-item key="detail" header="Detail">
|
||||
<a-collapse-item key="detail" :header="$t('util.detail')">
|
||||
<a-form layout="vertical" :model="{}">
|
||||
<a-form-item label="Issue Type">
|
||||
<a-form-item :label="$t('util.issueType')">
|
||||
{{info.issueType.name}}
|
||||
</a-form-item>
|
||||
<a-form-item label="Assigner">
|
||||
<a-form-item :label="$t('util.assigner')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.ASSIGNER" :value="info.assigner_id"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
<a-form-item label="Reporter">
|
||||
<a-form-item :label="$t('util.reporter')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.REPORTER" :value="info.reporter_id"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
<a-form-item label="Priority">
|
||||
<a-form-item :label="$t('util.priority')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.PRIORITY" :value="info.priority"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
<a-form-item label="Module">
|
||||
<a-form-item :label="$t('util.module')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.MODULE" :value="moduleList"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
<a-form-item label="Label">
|
||||
<a-form-item :label="$t('util.label')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.LABEL" :value="labelList"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
<a-form-item label="Fix Versions">
|
||||
<a-form-item :label="$t('util.fixVersions')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.FIXVERSIONS" :value="releaseList"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
<a-form-item label="Sprint">
|
||||
<a-form-item :label="$t('util.sprint')">
|
||||
<FieldEditBasic :project-issue-id="info.id" :type="EClient_Field_Basic_Type.SPRINT" :value="sprintInfo"></FieldEditBasic>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item key="more" header="More">
|
||||
<a-collapse-item key="more" :header="$t('util.more')">
|
||||
<a-form layout="vertical" :model="{}" v-if="fieldList.length>0">
|
||||
<a-form-item v-for="item in fieldList" :label="item.nodeField.field.name" :key="item.issueFieldValue.id">
|
||||
<FieldEdit :item="item"></FieldEdit>
|
||||
@ -38,7 +38,7 @@
|
||||
</a-collapse-item>
|
||||
</a-collapse>
|
||||
<a-row style="margin-top: 10px;color: grey;font-size: 12px;line-height: 1.3;padding-left: 5px;margin-bottom: 10px">
|
||||
Created {{moment(info.created_time).format('YYYY-MM-DD HH:mm:ss')}}
|
||||
{{$t("util.created")}} {{moment(info.created_time).format('YYYY-MM-DD HH:mm:ss')}}
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -6,35 +6,35 @@
|
||||
<template v-if="item.type===ECommon_Model_Project_Issue_History_Type.CREATE_ISSUE">
|
||||
<div style="width: 100%;align-items: center;display: flex">
|
||||
<UserAvatar :organization-user-id="item.organization_user_id"></UserAvatar>
|
||||
created the issue
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.createdTheIssue")}}
|
||||
<span style="color: grey">{{moment(item.created_time).format("YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Project_Issue_History_Type.APPROVAL_RESOLVE">
|
||||
<div style="width: 100%;align-items: center;display: flex">
|
||||
<UserAvatar :organization-user-id="item.organization_user_id"></UserAvatar>
|
||||
resolved your approval
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.resolvedYourApproval")}}
|
||||
<span style="color: grey">{{moment(item.created_time).format("YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Project_Issue_History_Type.APPROVAL_REJECT">
|
||||
<div style="width: 100%;align-items: center;display: flex">
|
||||
<UserAvatar :organization-user-id="item.organization_user_id"></UserAvatar>
|
||||
rejected your approval
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.rejectedYourApproval")}}
|
||||
<span style="color: grey">{{moment(item.created_time).format("YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Project_Issue_History_Type.UPDATE_FIELD">
|
||||
<div style="width: 100%;align-items: center;display: flex">
|
||||
<UserAvatar :organization-user-id="item.organization_user_id"></UserAvatar>
|
||||
updated the field
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.updatedTheField")}}
|
||||
<span style="color: blue">
|
||||
{{item.name}}
|
||||
</span>
|
||||
<span style="color: grey">{{moment(item.created_time).format("YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
<div v-if="item.value" style="display: flex;align-items: center">
|
||||
new value :
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.newValue")}} :
|
||||
<UserAvatar v-if="/\d{19,}/.test(item.value)" :organization-user-id="item.value"></UserAvatar>
|
||||
<span v-else style="color: grey">{{item.value}}</span>
|
||||
</div>
|
||||
@ -42,20 +42,20 @@
|
||||
<template v-else-if="item.type===ECommon_Model_Project_Issue_History_Type.UPDATE_NODE">
|
||||
<div style="width: 100%;align-items: center;display: flex">
|
||||
<UserAvatar :organization-user-id="item.organization_user_id"></UserAvatar>
|
||||
updated the workflow
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.updatedTheWorkflow")}}
|
||||
<span style="color: #544646">
|
||||
{{item.name}}
|
||||
</span>
|
||||
<span style="color: grey">{{moment(item.created_time).format("YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
<div>
|
||||
new workflow : <span style="color: grey">{{item.value}}</span>
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.newWorkflow")}} : <span style="color: grey">{{item.value}}</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="item.type===ECommon_Model_Project_Issue_History_Type.ISSUE_TYPE_CONVERT">
|
||||
<div style="width: 100%;align-items: center;display: flex">
|
||||
<UserAvatar :organization-user-id="item.organization_user_id"></UserAvatar>
|
||||
convert the issue
|
||||
{{$t("controller.app.project.issue.projectIssueHistory.convertTheIssue")}}
|
||||
<span style="color: grey">{{moment(item.created_time).format("YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -2,55 +2,55 @@
|
||||
<div>
|
||||
<a-row>
|
||||
<a-space wrap>
|
||||
Filter:
|
||||
<a-input-search v-model="keyword" placeholder="please type name or unique id" style="width: 250px" @search="onSearchIssue"></a-input-search>
|
||||
{{$t("util.filter")}}:
|
||||
<a-input-search v-model="keyword" :placeholder="$t('placeholder.typeNameOrUniqueId')" style="width: 250px" @search="onSearchIssue"></a-input-search>
|
||||
<a-select v-model="issueType">
|
||||
<template #label="{data}">
|
||||
<span>Issue Type:{{data?.label}}</span>
|
||||
<span>{{$t("util.issueType")}}:{{data?.label}}</span>
|
||||
</template>
|
||||
<a-option value="all" label="All"></a-option>
|
||||
<a-option value="all" :label="$t('util.all')"></a-option>
|
||||
<a-option v-for="item in issueTypeList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
<a-select style="width: 160px" v-model="priority">
|
||||
<template #label="{data}">
|
||||
<span>Priority:{{data?.label}}</span>
|
||||
<span>{{$t("util.priority")}}:{{data?.label}}</span>
|
||||
</template>
|
||||
<a-option :value="-1" label="All"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.LOW" label="low"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.MEDIUM" label="medium"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.HIGH" label="high"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.URGENT" label="urgent"></a-option>
|
||||
<a-option :value="-1" :label="$t('util.all')"></a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.LOW">{{$t('util.low')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.MEDIUM">{{$t('util.medium')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.HIGH">{{$t('util.high')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Issue_Priority.URGENT">{{$t('util.urgent')}}</a-option>
|
||||
</a-select>
|
||||
<a-select style="width: 170px" v-model="status">
|
||||
<template #label="{data}">
|
||||
<span>Status:{{data?.label}}</span>
|
||||
<span>{{$t("util.status")}}:{{data?.label}}</span>
|
||||
</template>
|
||||
<a-option :value="-1" label="All"></a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.NOTSTART" label="not start"></a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.INPROGRESS" label="in progress"></a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.DONE" label="done"></a-option>
|
||||
<a-option :value="-1" :label="$t('util.all')"></a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.NOTSTART">{{$t('util.notStart')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.INPROGRESS">{{$t('util.inProgress')}}</a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.DONE">{{$t('util.done')}}</a-option>
|
||||
</a-select>
|
||||
<a-cascader v-model="module" :field-names="fields" :options="moduleList" placeholder="please select" :format-label="format" check-strictly></a-cascader>
|
||||
Label:
|
||||
<a-select v-model="label" @search="onSearchLabel" allow-search placeholder="please type label">
|
||||
<a-option label="All" value="all"></a-option>
|
||||
<a-cascader v-model="module" :field-names="fields" :options="moduleList" :placeholder="$t('placeholder.pleaseSelect')" :format-label="format" check-strictly></a-cascader>
|
||||
{{$t("util.label")}}:
|
||||
<a-select v-model="label" @search="onSearchLabel" allow-search :placeholder="$t('placeholder.typeLabel')">
|
||||
<a-option :label="$t('util.all')" value="all"></a-option>
|
||||
<a-option v-for="item in labelList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
Assigner:
|
||||
<a-select v-model="assignerId" @search="onSearchAssigner" allow-search placeholder="please type assigner">
|
||||
<a-option label="All" value="all"></a-option>
|
||||
{{$t("util.assigner")}}:
|
||||
<a-select v-model="assignerId" @search="onSearchAssigner" allow-search :placeholder="$t('placeholder.typeAssigner')">
|
||||
<a-option :label="$t('util.all')" value="all"></a-option>
|
||||
<a-option v-for="item in assignerList" :label="item.organizationUser.nickname" :value="item.organizationUser.id"></a-option>
|
||||
</a-select>
|
||||
Reporter:
|
||||
<a-select v-model="reporterId" @search="onSearchReporter" allow-search placeholder="please type reporter">
|
||||
<a-option label="All" value="all"></a-option>
|
||||
{{$t("util.reporter")}}:
|
||||
<a-select v-model="reporterId" @search="onSearchReporter" allow-search :placeholder="$t('placeholder.typeReporter')">
|
||||
<a-option :label="$t('util.all')" value="all"></a-option>
|
||||
<a-option v-for="item in reporterList" :label="item.organizationUser.nickname" :value="item.organizationUser.id"></a-option>
|
||||
</a-select>
|
||||
<a-button type="primary" @click="onCreate" v-if="checkPermission(permission,Permission_Types.Project.EDIT)">Create</a-button>
|
||||
<a-button type="primary" @click="onCreate" v-if="checkPermission(permission,Permission_Types.Project.EDIT)">{{$t("util.create")}}</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-divider></a-divider>
|
||||
<span style="font-size: small;color: gray">If you wanna open in a new tab,hold command(Mac) or control(Win) Key,click the link below</span>
|
||||
<span style="font-size: small;color: gray">{{$t("controller.app.project.issue.projectIssueList.remark")}}</span>
|
||||
<a-table style="margin-top: 10px" :columns="columns" :data="issueList" :pagination="pagination" @pageChange="onPageChange">
|
||||
<template #type="{record}">
|
||||
{{record.issueType.name}}
|
||||
@ -73,9 +73,9 @@
|
||||
<FieldPriority :priority="record.priority"></FieldPriority>
|
||||
</template>
|
||||
<template #status="{record}">
|
||||
<a-tag color="gray" v-if="record.status===ECommon_Model_Workflow_Node_Status.NOTSTART">Not Start</a-tag>
|
||||
<a-tag color="blue" v-else-if="record.status===ECommon_Model_Workflow_Node_Status.INPROGRESS">InProgress</a-tag>
|
||||
<a-tag color="green" v-else-if="record.status===ECommon_Model_Workflow_Node_Status.DONE">Done</a-tag>
|
||||
<a-tag color="gray" v-if="record.status===ECommon_Model_Workflow_Node_Status.NOTSTART">{{$t("util.notStart")}}</a-tag>
|
||||
<a-tag color="blue" v-else-if="record.status===ECommon_Model_Workflow_Node_Status.INPROGRESS">{{$t("util.inProgress")}}</a-tag>
|
||||
<a-tag color="green" v-else-if="record.status===ECommon_Model_Workflow_Node_Status.DONE">{{$t("util.done")}}</a-tag>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
@ -108,11 +108,13 @@ import {ICommon_Model_Issue_Type} from "../../../../../../../common/model/issue_
|
||||
import ProjectIssueProfile from "./projectIssueProfile.vue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../../common/event/event";
|
||||
import {SessionStorage} from "../../../../common/storage/session";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const objInject=inject(injectProjectInfo)
|
||||
const projectId=objInject.id
|
||||
const permission=objInject.permission
|
||||
const key=objInject.key
|
||||
const {t}=useI18n()
|
||||
const fields={
|
||||
label:"name",
|
||||
value:"id",
|
||||
@ -120,7 +122,7 @@ const fields={
|
||||
}
|
||||
const columns=[
|
||||
{
|
||||
title:"Type",
|
||||
title:t("util.type"),
|
||||
slotName:"type"
|
||||
},
|
||||
{
|
||||
@ -128,7 +130,7 @@ const columns=[
|
||||
slotName: "key"
|
||||
},
|
||||
{
|
||||
title:"Name",
|
||||
title:t("util.name"),
|
||||
slotName: "name"
|
||||
},
|
||||
{
|
||||
@ -140,11 +142,11 @@ const columns=[
|
||||
slotName: "reporter"
|
||||
},
|
||||
{
|
||||
title:"Priority",
|
||||
title:t("util.priority"),
|
||||
slotName: "priority"
|
||||
},
|
||||
{
|
||||
title:"Status",
|
||||
title:t("util.status"),
|
||||
slotName: "status"
|
||||
}
|
||||
]
|
||||
|
@ -5,9 +5,9 @@
|
||||
<a-row style="width: 300px;padding: 10px">
|
||||
<a-row style="color: gray;width: 100%">
|
||||
{{info?.project.keyword+"-"+info?.unique_id}}
|
||||
<a-tag color="gray" v-if="info?.workflowNode.status===ECommon_Model_Workflow_Node_Status.NOTSTART">Not Start</a-tag>
|
||||
<a-tag color="blue" v-else-if="info?.workflowNode.status===ECommon_Model_Workflow_Node_Status.INPROGRESS">InProgress</a-tag>
|
||||
<a-tag color="green" v-else-if="info?.workflowNode.status===ECommon_Model_Workflow_Node_Status.DONE">Done</a-tag>
|
||||
<a-tag color="gray" v-if="info?.workflowNode.status===ECommon_Model_Workflow_Node_Status.NOTSTART">{{$t("util.notStart")}}</a-tag>
|
||||
<a-tag color="blue" v-else-if="info?.workflowNode.status===ECommon_Model_Workflow_Node_Status.INPROGRESS">{{$t("util.inProgress")}}</a-tag>
|
||||
<a-tag color="green" v-else-if="info?.workflowNode.status===ECommon_Model_Workflow_Node_Status.DONE">{{$t("util.done")}}</a-tag>
|
||||
</a-row>
|
||||
<a-row style="font-weight: bold;width: 100%;margin-top: 10px">
|
||||
{{info?.name}}
|
||||
@ -15,14 +15,14 @@
|
||||
<a-row style="width: 100%;margin-top: 15px">
|
||||
<a-col :span="12">
|
||||
<template v-if="info?.assigner_id">
|
||||
Assigner
|
||||
{{$t("util.assigner")}}
|
||||
<a-avatar :image-url="info?.assigner_id.photo" :size="20"></a-avatar>
|
||||
{{info?.assigner_id.nickname}}
|
||||
</template>
|
||||
</a-col>
|
||||
<a-col :span="12">
|
||||
<template v-if="info?.reporter_id">
|
||||
Reporter
|
||||
{{$t("util.reporter")}}
|
||||
<a-avatar :image-url="info?.reporter_id.photo" :size="20"></a-avatar>
|
||||
{{info?.reporter_id.nickname}}
|
||||
</template>
|
||||
@ -36,7 +36,7 @@
|
||||
<FieldPriority :priority="info?.priority" v-if="info"></FieldPriority>
|
||||
</a-col>
|
||||
<a-col :span="8">
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @click="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="mini" style="margin-left: 20px" @click="onProfile">{{$t("util.profile")}}</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-row>
|
||||
|
@ -13,7 +13,7 @@
|
||||
</a-row>
|
||||
<a-row v-if="info?.approval?.type===ECommon_Model_Project_Issue_Approval_Type.REJECTED" style="align-items: center;margin-top: 10px;">
|
||||
<UserAvatar :organization-user-id="info.approval.approval_organization_user_id"></UserAvatar>
|
||||
<span style="color: orange;font-weight: bold"> rejected your approval</span>
|
||||
<span style="color: orange;font-weight: bold"> {{$t("controller.app.project.issue.projectIssueHistory.rejectedYourApproval")}}</span>
|
||||
<a-popover v-if="info.approval.reason" position="right">
|
||||
<icon-info-circle-fill style="color: orange;margin-left: 10px"></icon-info-circle-fill>
|
||||
<template #content>
|
||||
@ -31,17 +31,17 @@
|
||||
</template>
|
||||
</a-dropdown>
|
||||
<a-button v-if="!parentIssue" @click="onCreateSubIssue">
|
||||
Create Child Issue
|
||||
{{$t("controller.app.project.issue.projectIssueProfile.createChildIssue")}}
|
||||
</a-button>
|
||||
<a-dropdown-button>
|
||||
Link Issue
|
||||
{{$t("controller.app.project.issue.projectIssueProfile.linkIssue")}}
|
||||
<template #icon>
|
||||
<icon-down />
|
||||
</template>
|
||||
<template #content>
|
||||
<a-doption @click="onAddItem('related')">Related</a-doption>
|
||||
<a-doption @click="onAddItem('child')">Child</a-doption>
|
||||
<a-doption @click="onAddItem('parent')">Parent</a-doption>
|
||||
<a-doption @click="onAddItem('related')">{{$t("controller.app.project.issue.projectIssueProfile.related")}}</a-doption>
|
||||
<a-doption @click="onAddItem('child')">{{$t("controller.app.project.issue.projectIssueProfile.child")}}</a-doption>
|
||||
<a-doption @click="onAddItem('parent')">{{$t("controller.app.project.issue.projectIssueProfile.parent")}}</a-doption>
|
||||
</template>
|
||||
</a-dropdown-button>
|
||||
<a-dropdown>
|
||||
@ -52,38 +52,38 @@
|
||||
</a-button>
|
||||
<template #content>
|
||||
<a-popover trigger="hover" position="rt" @popup-visible-change="showQuickMeeting">
|
||||
<a-doption>Quick Meeting</a-doption>
|
||||
<a-doption>{{$t("controller.app.project.issue.projectIssueProfile.quickMeeting")}}</a-doption>
|
||||
<template #content>
|
||||
<a-row style="flex-direction: column;align-items: center">
|
||||
<a-input size="small" placeholder="type user name" v-model="searchUserKey"></a-input>
|
||||
<a-input size="small" :placeholder="$t('placeholder.typeUserName')" v-model="searchUserKey"></a-input>
|
||||
<a-table style="width: 100%;margin-top: 10px" row-key="id" :columns="columns" :data="issueRelatedUserList.filter(item=>(item.id!==organizationUserId && item.name.includes(searchUserKey)))" :row-selection="rowSelection" v-model:selected-keys="selectKeys" :pagination="false">
|
||||
<template #name="{record}">
|
||||
<UserAvatar :organization-user-id="record.id" :name="record.name" :photo="record.photo"></UserAvatar>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-button type="primary" style="margin-top: 10px" size="small" @click="onMeeting">Invite</a-button>
|
||||
<a-button type="primary" style="margin-top: 10px" size="small" @click="onMeeting">{{$t("util.invite")}}</a-button>
|
||||
</a-row>
|
||||
</template>
|
||||
</a-popover>
|
||||
<a-doption v-if="checkPermission(permission,Permission_Types.Project.EDIT)" @click="onCopy">Copy</a-doption>
|
||||
<a-doption v-if="checkPermission(permission,Permission_Types.Project.EDIT)" @click="onConvert">Convert</a-doption>
|
||||
<a-doption v-if="checkPermission(permission,Permission_Types.Project.ADMIN) || info?.created_by.id===store.userInfo.id" @click="onDelete" style="color: red">Delete</a-doption>
|
||||
<a-doption v-if="checkPermission(permission,Permission_Types.Project.EDIT)" @click="onCopy">{{$t("util.copy")}}</a-doption>
|
||||
<a-doption v-if="checkPermission(permission,Permission_Types.Project.EDIT)" @click="onConvert">{{$t("util.convert")}}</a-doption>
|
||||
<a-doption v-if="checkPermission(permission,Permission_Types.Project.ADMIN) || info?.created_by.id===store.userInfo.id" @click="onDelete" style="color: red">{{$t("util.delete")}}</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-row style="margin-top: 20px;font-weight: bold">
|
||||
Description
|
||||
{{$t("util.description")}}
|
||||
</a-row>
|
||||
<a-row style="margin-top: 10px">
|
||||
<FieldEditBasic :project-issue-id="projectIssueId" :type="EClient_Field_Basic_Type.DESCRIPTION" :value="description" style="margin-right: 10px;box-sizing: border-box"></FieldEditBasic>
|
||||
</a-row>
|
||||
<ProjectIssueRelated :project-issue-id="projectIssueId" :child-issue-list="childIssueList" :parent-issue="parentIssue" :related-issue-list="relatedIssueList" @remove-parent="parentIssue=null"></ProjectIssueRelated>
|
||||
<a-tabs type="rounded" style="margin-top: 50px;" lazy-load size="small">
|
||||
<a-tab-pane key="comment" title="Comments">
|
||||
<a-tab-pane key="comment" :title="$t('util.comments')">
|
||||
<ProjectIssueComment style="margin-top: 10px" :project-issue-id="projectIssueId"></ProjectIssueComment>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="history" title="History">
|
||||
<a-tab-pane key="history" :title="$t('util.history')">
|
||||
<ProjectIssueHistory :project-issue-id="projectIssueId"></ProjectIssueHistory>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
@ -132,6 +132,7 @@ import {ECommon_Content_Line_Config_Type} from "../../../../../../../common/mode
|
||||
import {RichEditorEventHandle} from "@/business/common/component/richEditorEventHandle";
|
||||
import {ECommon_Model_Finder_Shortcut_Type} from "../../../../../../../common/model/finder_item";
|
||||
import ProjectIssueConvert from "@/business/controller/app/project/issue/projectIssueConvert.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectIssueId:string
|
||||
@ -168,9 +169,10 @@ const rowSelection=ref<TableRowSelection>({
|
||||
showCheckedAll:true,
|
||||
onlyCurrent:false
|
||||
})
|
||||
const {t}=useI18n()
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
title: t("util.name"),
|
||||
slotName: 'name',
|
||||
}
|
||||
]
|
||||
@ -261,13 +263,13 @@ const onAddItem=async (type:"parent"|"child"|"related")=>{
|
||||
}
|
||||
|
||||
const onDelete=async ()=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this issue?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteIssue"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.remove({
|
||||
projectIssueId:props.projectIssueId
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
navigator.pop()
|
||||
}
|
||||
}
|
||||
@ -302,7 +304,7 @@ const onAction=async (item:ICommon_Model_Workflow_Action | {
|
||||
return
|
||||
}
|
||||
} else if(item.name==="Reject") {
|
||||
let ret=await Dialog.inputRich(root.value,appContext,"Reject Reason")
|
||||
let ret=await Dialog.inputRich(root.value,appContext,t("tip.rejectReason"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.rejectApproval({
|
||||
projectIssueId:props.projectIssueId,
|
||||
@ -367,7 +369,7 @@ const onMeeting=async ()=>{
|
||||
}
|
||||
|
||||
const onCopy=async ()=>{
|
||||
let ret=await Dialog.input(root.value,appContext,"type the issue's name")
|
||||
let ret=await Dialog.input(root.value,appContext,t("tip.typeIssueName"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.copy({
|
||||
projectIssueId:props.projectIssueId,
|
||||
@ -393,7 +395,7 @@ const onConvert=async ()=>{
|
||||
}
|
||||
|
||||
const onCreateSubIssue=async ()=>{
|
||||
let ret=await Dialog.input(root.value,appContext,"type the issue's name")
|
||||
let ret=await Dialog.input(root.value,appContext,t("tip.typeIssueName"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.createChildIssue({
|
||||
projectIssueId:props.projectIssueId,
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-if="parentIssue">
|
||||
<a-row style="margin-top: 20px;font-weight: bold">Parent Issue</a-row>
|
||||
<a-row style="margin-top: 20px;font-weight: bold">{{$t("controller.app.project.issue.projectIssueRelated.parentIssue")}}</a-row>
|
||||
<a-list style="margin-top: 10px;margin-right: 10px" size="small" hoverable>
|
||||
<a-list-item>
|
||||
<a-space size="large">
|
||||
@ -20,7 +20,7 @@
|
||||
</a-list>
|
||||
</template>
|
||||
<template v-if="childIssueList.length>0">
|
||||
<a-row style="margin-top: 20px;font-weight: bold">Child Issues</a-row>
|
||||
<a-row style="margin-top: 20px;font-weight: bold">{{$t("controller.app.project.issue.projectIssueRelated.childIssues")}}</a-row>
|
||||
<a-list style="margin-top: 10px;margin-right: 10px" size="small" hoverable>
|
||||
<a-list-item v-for="(item,index) in childIssueList" :key="item.id">
|
||||
<a-space size="large">
|
||||
@ -39,7 +39,7 @@
|
||||
</a-list>
|
||||
</template>
|
||||
<template v-if="relatedIssueList.length>0">
|
||||
<a-row style="margin-top: 20px;font-weight: bold">Related Issues</a-row>
|
||||
<a-row style="margin-top: 20px;font-weight: bold">{{$t("controller.app.project.issue.projectIssueRelated.relatedIssues")}}</a-row>
|
||||
<a-list style="margin-top: 10px;margin-right: 10px" size="small" hoverable>
|
||||
<a-list-item v-for="(item,index) in relatedIssueList" :key="item.id">
|
||||
<a-space size="large">
|
||||
@ -70,6 +70,7 @@ import {injectProjectInfo} from "../../../../common/util/symbol";
|
||||
import {Dialog} from "../../../../common/component/dialog/dialog";
|
||||
import {getRootNavigatorRef} from "../../../../../teamOS/common/component/navigator/navigator";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../../common/event/event";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
parentIssue?:DCSType<ICommon_Model_Project_Issue>,
|
||||
@ -84,9 +85,10 @@ const key=inject(injectProjectInfo).key
|
||||
const projectId=inject(injectProjectInfo).id
|
||||
const root=getRootNavigatorRef()
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const {t}=useI18n()
|
||||
const onRemoveItem=async (type:"parent"|"child"|"related",index:number)=>{
|
||||
if(type==="parent") {
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to remove parent issue?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteParentIssue"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.removeParentIssue({
|
||||
projectIssueId:props.projectIssueId,
|
||||
@ -97,7 +99,7 @@ const onRemoveItem=async (type:"parent"|"child"|"related",index:number)=>{
|
||||
}
|
||||
}
|
||||
} else if(type=="child") {
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to remove child issue?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteChildIssue"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.removeChildIssue({
|
||||
projectIssueId:props.projectIssueId,
|
||||
@ -108,7 +110,7 @@ const onRemoveItem=async (type:"parent"|"child"|"related",index:number)=>{
|
||||
}
|
||||
}
|
||||
} else if(type=="related") {
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to remove related issue?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteRelatedIssue"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.removeRelatedIssue({
|
||||
projectIssueId:props.projectIssueId,
|
||||
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div style="height: 100%;overflow-y: auto;padding: 0px 10px" ref="root">
|
||||
Your Work
|
||||
{{$t("controller.app.project.project.yourWork")}}
|
||||
<a-collapse :default-active-key="['recent','all']" style="margin-top: 10px">
|
||||
<a-collapse-item header="Recent Project List" key="recent">
|
||||
<a-collapse-item :header="$t('controller.app.project.project.recentProjectList')" key="recent">
|
||||
<a-space wrap style="margin-top: 20px" size="large" v-if="recentList.length>0">
|
||||
<ProjectItem v-for="item in recentList" style="background-color: white" done-title="my done issue" :done-count="item.done" open-title="my open issue" :open-count="item.notstart+item.inprogress" :name="item.name" :project-id="item.id" :photo="item.photo" @click="onClickProjectItem(item.id,item.name)" v-drag.shortcut="()=>({
|
||||
shortcutType:ECommon_Model_Finder_Shortcut_Type.PROJECT,
|
||||
@ -12,17 +12,17 @@
|
||||
</a-space>
|
||||
<a-empty v-else></a-empty>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="All Project List" key="all">
|
||||
<a-collapse-item :header="$t('controller.app.project.project.allProjectList')" key="all">
|
||||
<a-row>
|
||||
<a-space>
|
||||
Type
|
||||
{{$t("util.type")}}
|
||||
<a-select v-model="type" style="width: 100px">
|
||||
<a-option label="All" value="all"></a-option>
|
||||
<a-option label="Created" value="created"></a-option>
|
||||
<a-option label="Joined" value="joined"></a-option>
|
||||
<a-option :label="$t('util.all')" value="all"></a-option>
|
||||
<a-option :label="$t('util.created')" value="created"></a-option>
|
||||
<a-option :label="$t('util.joined')" value="joined"></a-option>
|
||||
</a-select>
|
||||
<a-input-search style="width: 250px" v-model="keyword" placeholder="please type project name" @search="onSearch"></a-input-search>
|
||||
<a-button type="primary" @click="onAddProject" v-if="checkPermission(storeOrganization.organizationPermission,Permission_Types.Organization.CREATE_PROJECT)">Create</a-button>
|
||||
<a-input-search style="width: 250px" v-model="keyword" :placeholder="$t('placeholder.typeProjectName')" @search="onSearch"></a-input-search>
|
||||
<a-button type="primary" @click="onAddProject" v-if="checkPermission(storeOrganization.organizationPermission,Permission_Types.Organization.CREATE_PROJECT)">{{$t("util.create")}}</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-space wrap style="margin-top: 20px" size="large" v-if="list.length>0">
|
||||
|
@ -2,11 +2,11 @@
|
||||
<a-layout style="height: 100%">
|
||||
<a-layout-sider :resize-directions="['right']">
|
||||
<a-menu style="width: 100%" @menu-item-click="onSubMenuClick" v-model:selected-keys="menuKey">
|
||||
<a-menu-item key="home">Home</a-menu-item>
|
||||
<a-menu-item key="issue">Issue</a-menu-item>
|
||||
<a-menu-item key="board">Board</a-menu-item>
|
||||
<a-menu-item key="release">Release</a-menu-item>
|
||||
<a-menu-item key="setting" v-if="checkPermission(permission,Permission_Types.Project.ADMIN)">Setting</a-menu-item>
|
||||
<a-menu-item key="home">{{$t("util.home")}}</a-menu-item>
|
||||
<a-menu-item key="issue">{{$t("util.issue")}}</a-menu-item>
|
||||
<a-menu-item key="board">{{$t("util.board")}}</a-menu-item>
|
||||
<a-menu-item key="release">{{$t("util.release")}}</a-menu-item>
|
||||
<a-menu-item key="setting" v-if="checkPermission(permission,Permission_Types.Project.ADMIN)">{{$t("util.setting")}}</a-menu-item>
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<a-layout-content style="flex-direction: column;display: flex;padding: 10px;">
|
||||
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm">
|
||||
<a-form-item label="name" field="name" required>
|
||||
<a-form-item :label="$t('util.name')" field="name" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="description" field="description">
|
||||
<a-form-item :label="$t('util.description')" field="description">
|
||||
<a-textarea v-model="form.description" allow-clear></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label="dateRange" field="dateRange" required>
|
||||
<a-range-picker v-model="form.dateRange" :placeholder="['Start Date','Release Date']"></a-range-picker>
|
||||
<a-form-item :label="$t('util.dateRange')" field="dateRange" required>
|
||||
<a-range-picker v-model="form.dateRange" :placeholder="[$t('util.startDate'),$t('util.releaseDate')]"></a-range-picker>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
@ -19,12 +19,14 @@ import {reactive, ref} from "vue";
|
||||
import {onDialogOk} from "../../../../common/component/dialog/dialog";
|
||||
import {dialogFuncGenerator} from "../../../../common/util/helper";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
type:"add"|"edit",
|
||||
projectId?:string,
|
||||
item?:DCSType<ICommon_Route_Res_Release_Item>
|
||||
}>()
|
||||
const {t}=useI18n()
|
||||
const form=reactive({
|
||||
name:props.type=="edit"?props.item.name:"",
|
||||
dateRange:props.type=="edit"?[props.item.start_time,props.item.release_time]:["",""],
|
||||
@ -34,7 +36,7 @@ const eleForm=ref(null)
|
||||
onDialogOk(dialogFuncGenerator({
|
||||
func:()=>{
|
||||
if(!form.dateRange[0] || !form.dateRange[1]) {
|
||||
Message.error("you must select both date!")
|
||||
Message.error(t("tip.selectBothDate"))
|
||||
return false;
|
||||
}
|
||||
return props.type=="add"?apiRelease.create({
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
there are still <span style="font-weight: bold;color: blue">{{items.length}}</span> unresolved issues!<br><br>
|
||||
<span style="font-weight: bold;color: red">Do you Still continue to Release?</span>
|
||||
{{$t("controller.app.project.release.projectReleaseIfCan.thereAreStill")}} <span style="font-weight: bold;color: blue">{{items.length}}</span> {{$t("controller.app.project.release.projectReleaseIfCan.unresolvedIssues")}}!<br><br>
|
||||
<span style="font-weight: bold;color: red">{{$t("controller.app.project.release.projectReleaseIfCan.continueToRelease")}}?</span>
|
||||
<a-table style="margin-top: 15px" :data="items" :columns="columns">
|
||||
<template #key="{record}">
|
||||
{{projectKey+"-"+record.unique_id}}
|
||||
@ -31,6 +31,7 @@ import {onDialogOk} from "../../../../common/component/dialog/dialog";
|
||||
import {ECommon_Model_Project_Release_Status} from "../../../../../../../common/model/project_release";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../../common/event/event";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectReleaseId:string,
|
||||
@ -38,17 +39,18 @@ const props=defineProps<{
|
||||
projectKey:string,
|
||||
projectId:string
|
||||
}>()
|
||||
const {t}=useI18n()
|
||||
const columns=[
|
||||
{
|
||||
title:"Key",
|
||||
slotName: "key"
|
||||
},
|
||||
{
|
||||
title:"Name",
|
||||
title:t("util.name"),
|
||||
slotName:"name"
|
||||
},
|
||||
{
|
||||
title:"Priority",
|
||||
title:t("util.priority"),
|
||||
slotName: "priority"
|
||||
},
|
||||
{
|
||||
@ -69,7 +71,7 @@ onDialogOk(async ()=>{
|
||||
status:ECommon_Model_Project_Release_Status.RELEASE
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("release success")
|
||||
Message.success(t("tip.releaseSuccess"))
|
||||
return true;
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
|
@ -2,17 +2,17 @@
|
||||
<div>
|
||||
<a-row>
|
||||
<a-space wrap>
|
||||
<a-input-search v-model="keyword" placeholder="please type release name" style="width: 250px" @search="onSearch"></a-input-search>
|
||||
<a-input-search v-model="keyword" :placeholder="$t('placeholder.typeReleaseName')" style="width: 250px" @search="onSearch"></a-input-search>
|
||||
<a-select v-model="status">
|
||||
<template #label="{data}">
|
||||
<span>Status:{{data?.label}}</span>
|
||||
<span>{{$t("util.status")}}:{{data?.label}}</span>
|
||||
</template>
|
||||
<a-option :value="-1">ALL</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Release_Status.ARCHIVED">ARCHIVED</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Release_Status.RELEASE">RELEASED</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Release_Status.UNRELEASE">UNRELEASED</a-option>
|
||||
<a-option :value="-1">{{$t("util.all")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Release_Status.ARCHIVED">{{$t("util.archived")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Release_Status.RELEASE">{{$t("util.released")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Project_Release_Status.UNRELEASE">{{$t("util.unReleased")}}</a-option>
|
||||
</a-select>
|
||||
<a-button type="primary" @click="onCreate" v-if="checkPermission(permission,Permission_Types.Project.EDIT)">Create</a-button>
|
||||
<a-button type="primary" @click="onCreate" v-if="checkPermission(permission,Permission_Types.Project.EDIT)">{{$t("util.create")}}</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-table style="margin-top: 10px" :columns="columns" :data="releaseList" :pagination="pagination" @pageChange="onPageChange">
|
||||
@ -20,13 +20,13 @@
|
||||
<a-link href="javascript:void(0)" @click="onProfile(record,$event)">{{record.name}}</a-link>
|
||||
</template>
|
||||
<template #status="{record}">
|
||||
<a-tag color="blue" v-if="record.status===ECommon_Model_Project_Release_Status.UNRELEASE">UNRELEASED</a-tag>
|
||||
<a-tag color="green" v-else-if="record.status===ECommon_Model_Project_Release_Status.RELEASE">RELEASED</a-tag>
|
||||
<a-tag v-else-if="record.status===ECommon_Model_Project_Release_Status.ARCHIVED">ARCHIVED</a-tag>
|
||||
<a-tag color="blue" v-if="record.status===ECommon_Model_Project_Release_Status.UNRELEASE">{{$t("util.unReleased")}}</a-tag>
|
||||
<a-tag color="green" v-else-if="record.status===ECommon_Model_Project_Release_Status.RELEASE">{{$t("util.released")}}</a-tag>
|
||||
<a-tag v-else-if="record.status===ECommon_Model_Project_Release_Status.ARCHIVED">{{$t("util.archived")}}</a-tag>
|
||||
</template>
|
||||
<template #progress="{record}">
|
||||
<span v-if="record.notstart+record.inprogress+record.done==0">
|
||||
No Issues
|
||||
{{$t("controller.app.project.release.projectReleaseList.noIssues")}}
|
||||
</span>
|
||||
<a-progress v-else :percent="record.done/(record.notstart+record.inprogress+record.done)" style="width: 180px" color="green"></a-progress>
|
||||
</template>
|
||||
@ -41,28 +41,28 @@
|
||||
</template>
|
||||
<template #operation="{record}">
|
||||
<a-space v-if="checkPermission(permission,Permission_Types.Project.EDIT)" wrap>
|
||||
<a-button size="small" @click="onEdit(record)">Edit</a-button>
|
||||
<a-button size="small" @click="onEdit(record)">{{$t("util.edit")}}</a-button>
|
||||
<a-dropdown-button size="small">
|
||||
Action
|
||||
{{$t("util.action")}}
|
||||
<template #icon>
|
||||
<icon-down />
|
||||
</template>
|
||||
<template #content>
|
||||
<template v-if="record.status==ECommon_Model_Project_Release_Status.ARCHIVED">
|
||||
<a-doption @click="onUnRelease(record)">UnRelease</a-doption>
|
||||
<a-doption @click="onRelease(record)">Release</a-doption>
|
||||
<a-doption @click="onUnRelease(record)">{{$t("util.unRelease")}}</a-doption>
|
||||
<a-doption @click="onRelease(record)">{{$t("util.release")}}</a-doption>
|
||||
</template>
|
||||
<template v-else-if="record.status==ECommon_Model_Project_Release_Status.RELEASE">
|
||||
<a-doption @click="onUnRelease(record)">UnRelease</a-doption>
|
||||
<a-doption @click="onArchive(record)">Archive</a-doption>
|
||||
<a-doption @click="onUnRelease(record)">{{$t("util.unRelease")}}</a-doption>
|
||||
<a-doption @click="onArchive(record)">{{$t("util.archive")}}</a-doption>
|
||||
</template>
|
||||
<template v-if="record.status==ECommon_Model_Project_Release_Status.UNRELEASE">
|
||||
<a-doption @click="onRelease(record)">Release</a-doption>
|
||||
<a-doption @click="onArchive(record)">Archive</a-doption>
|
||||
<a-doption @click="onRelease(record)">{{$t("util.release")}}</a-doption>
|
||||
<a-doption @click="onArchive(record)">{{$t("util.archive")}}</a-doption>
|
||||
</template>
|
||||
</template>
|
||||
</a-dropdown-button>
|
||||
<a-button size="small" status="danger" @click="onDelete(record)">Delete</a-button>
|
||||
<a-button size="small" status="danger" @click="onDelete(record)">{{$t("util.delete")}}</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-table>
|
||||
@ -88,38 +88,40 @@ import {Message} from "@arco-design/web-vue";
|
||||
import ProjectReleaseIfCan from "./projectReleaseIfCan.vue";
|
||||
import ProjectReleaseProfile from "./projectReleaseProfile.vue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../../common/event/event";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const objInject=inject(injectProjectInfo)
|
||||
const projectId=objInject.id
|
||||
const permission=objInject.permission
|
||||
const key=objInject.key
|
||||
const {t}=useI18n()
|
||||
const columns=[
|
||||
{
|
||||
title:"Name",
|
||||
title:t("util.name"),
|
||||
slotName:"name"
|
||||
},
|
||||
{
|
||||
title:"Status",
|
||||
title:t("util.status"),
|
||||
slotName: "status"
|
||||
},
|
||||
{
|
||||
title:"Progress",
|
||||
title:t("util.progress"),
|
||||
slotName: "progress"
|
||||
},
|
||||
{
|
||||
title:"Start Date",
|
||||
title:t("util.startDate"),
|
||||
slotName: "startDate"
|
||||
},
|
||||
{
|
||||
title:"Release Date",
|
||||
title:t("util.releaseDate"),
|
||||
slotName: "releaseDate"
|
||||
},
|
||||
{
|
||||
title:"Description",
|
||||
title:t("util.description"),
|
||||
slotName: "description"
|
||||
},
|
||||
{
|
||||
title:"Operation",
|
||||
title:t("util.operation"),
|
||||
slotName: "operation"
|
||||
}
|
||||
]
|
||||
@ -177,13 +179,13 @@ const onEdit=async (item:DCSType<ICommon_Route_Res_Release_Item>)=>{
|
||||
}
|
||||
}
|
||||
const onDelete=async (item:DCSType<ICommon_Route_Res_Release_Item>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this release?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteRelease"))
|
||||
if(ret) {
|
||||
let res=await apiRelease.remove({
|
||||
projectReleaseId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
search(pagination.current)
|
||||
}
|
||||
}
|
||||
@ -209,7 +211,7 @@ const onRelease=async (item:DCSType<ICommon_Route_Res_Release_Item>)=>{
|
||||
status:ECommon_Model_Project_Release_Status.RELEASE
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("release success")
|
||||
Message.success(t("tip.releaseSuccess"))
|
||||
search(pagination.current)
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
@ -225,7 +227,7 @@ const onUnRelease=async (item:DCSType<ICommon_Route_Res_Release_Item>)=>{
|
||||
status:ECommon_Model_Project_Release_Status.UNRELEASE
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("unrelease success")
|
||||
Message.success(t("tip.unReleaseSuccess"))
|
||||
search(pagination.current)
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
@ -237,7 +239,7 @@ const onArchive=async (item:DCSType<ICommon_Route_Res_Release_Item>)=>{
|
||||
status:ECommon_Model_Project_Release_Status.ARCHIVED
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("archive success")
|
||||
Message.success(t("tip.archiveSuccess"))
|
||||
search(pagination.current)
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
|
@ -8,9 +8,9 @@
|
||||
<span style="font-weight: bold">
|
||||
{{info?.name}}
|
||||
</span>
|
||||
<a-tag color="gray" v-if="info?.status===ECommon_Model_Project_Release_Status.ARCHIVED">ARCHIVED</a-tag>
|
||||
<a-tag color="blue" v-else-if="info?.status===ECommon_Model_Project_Release_Status.UNRELEASE">UNRELEASED</a-tag>
|
||||
<a-tag color="green" v-else-if="info?.status===ECommon_Model_Project_Release_Status.RELEASE">RELEASED</a-tag>
|
||||
<a-tag color="gray" v-if="info?.status===ECommon_Model_Project_Release_Status.ARCHIVED">{{$t("util.archived")}}</a-tag>
|
||||
<a-tag color="blue" v-else-if="info?.status===ECommon_Model_Project_Release_Status.UNRELEASE">{{$t("util.unReleased")}}</a-tag>
|
||||
<a-tag color="green" v-else-if="info?.status===ECommon_Model_Project_Release_Status.RELEASE">{{$t("util.released")}}</a-tag>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-row style="width: 100%;margin-top: 10px">
|
||||
@ -25,12 +25,12 @@
|
||||
<a-row style="width: 100%;margin-top: 10px">
|
||||
<a-col :span="16">
|
||||
<span v-if="info?.notstart+info?.inprogress+info?.done==0">
|
||||
No Issues
|
||||
{{$t("controller.app.project.release.projectReleaseList.noIssues")}}
|
||||
</span>
|
||||
<a-progress v-else :percent="info?.done/(info?.notstart+info?.inprogress+info?.done)" style="width: 100%" color="green"></a-progress>
|
||||
</a-col>
|
||||
<a-col :span="8" style="text-align: center">
|
||||
<a-button type="outline" size="mini" @click="onProfile">Profile</a-button>
|
||||
<a-button type="outline" size="mini" @click="onProfile">{{$t("util.profile")}}</a-button>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-row>
|
||||
|
@ -9,33 +9,33 @@
|
||||
})">
|
||||
{{info?.name}}
|
||||
</span>
|
||||
<a-tag color="blue" v-if="info?.status===ECommon_Model_Project_Release_Status.UNRELEASE">UNRELEASED</a-tag>
|
||||
<a-tag color="green" v-else-if="info?.status===ECommon_Model_Project_Release_Status.RELEASE">RELEASED</a-tag>
|
||||
<a-tag v-else-if="info?.status===ECommon_Model_Project_Release_Status.ARCHIVED">ARCHIVED</a-tag>
|
||||
<a-tag color="blue" v-if="info?.status===ECommon_Model_Project_Release_Status.UNRELEASE">{{$t("util.unReleased")}}</a-tag>
|
||||
<a-tag color="green" v-else-if="info?.status===ECommon_Model_Project_Release_Status.RELEASE">{{$t("util.released")}}</a-tag>
|
||||
<a-tag v-else-if="info?.status===ECommon_Model_Project_Release_Status.ARCHIVED">{{$t("util.archived")}}</a-tag>
|
||||
</a-space>
|
||||
<a-space>
|
||||
<a-button size="small" @click="onEdit">Edit</a-button>
|
||||
<a-button size="small" @click="onEdit">{{$t("util.edit")}}</a-button>
|
||||
<a-dropdown-button size="small">
|
||||
Action
|
||||
{{$t("util.action")}}
|
||||
<template #icon>
|
||||
<icon-down />
|
||||
</template>
|
||||
<template #content>
|
||||
<template v-if="info?.status==ECommon_Model_Project_Release_Status.ARCHIVED">
|
||||
<a-doption @click="onUnRelease">UnRelease</a-doption>
|
||||
<a-doption @click="onRelease">Release</a-doption>
|
||||
<a-doption @click="onUnRelease">{{$t("util.unRelease")}}</a-doption>
|
||||
<a-doption @click="onRelease">{{$t("util.release")}}</a-doption>
|
||||
</template>
|
||||
<template v-else-if="info?.status==ECommon_Model_Project_Release_Status.RELEASE">
|
||||
<a-doption @click="onUnRelease">UnRelease</a-doption>
|
||||
<a-doption @click="onArchive">Archive</a-doption>
|
||||
<a-doption @click="onUnRelease">{{$t("util.unRelease")}}</a-doption>
|
||||
<a-doption @click="onArchive">{{$t("util.archive")}}</a-doption>
|
||||
</template>
|
||||
<template v-if="info?.status==ECommon_Model_Project_Release_Status.UNRELEASE">
|
||||
<a-doption @click="onRelease">Release</a-doption>
|
||||
<a-doption @click="onArchive">Archive</a-doption>
|
||||
<a-doption @click="onRelease">{{$t("util.release")}}</a-doption>
|
||||
<a-doption @click="onArchive">{{$t("util.archive")}}</a-doption>
|
||||
</template>
|
||||
</template>
|
||||
</a-dropdown-button>
|
||||
<a-button size="small" status="danger" @click="onDelete">Delete</a-button>
|
||||
<a-button size="small" status="danger" @click="onDelete">{{$t("util.delete")}}</a-button>
|
||||
</a-space>
|
||||
</a-row>
|
||||
<a-row style="margin-top: 20px">
|
||||
@ -51,8 +51,8 @@
|
||||
{{info?.description}}
|
||||
</a-row>
|
||||
<a-row style="justify-content: space-between;margin-top: 30px">
|
||||
<span style="font-weight: bold">Issues</span>
|
||||
<a-button type="primary" size="small" @click="onAddIssue">Add Issue</a-button>
|
||||
<span style="font-weight: bold">{{$t("util.issues")}}</span>
|
||||
<a-button type="primary" size="small" @click="onAddIssue">{{$t("controller.app.project.release.projectReleaseProfile.addIssue")}}</a-button>
|
||||
</a-row>
|
||||
<a-table style="margin-top: 10px" :data="info?.issueList" :columns="columns">
|
||||
<template #key="{record}">
|
||||
@ -74,9 +74,9 @@
|
||||
<UserAvatar :organization-user-id="record.reporter_id.organizationUserId" :name="record.reporter_id.nickname" :photo="record.reporter_id.photo" v-if="record.reporter_id"></UserAvatar>
|
||||
</template>
|
||||
<template #status="{record}">
|
||||
<a-tag color="gray" v-if="record.workflowNode.status===ECommon_Model_Workflow_Node_Status.NOTSTART">Not Start</a-tag>
|
||||
<a-tag color="blue" v-else-if="record.workflowNode.status===ECommon_Model_Workflow_Node_Status.INPROGRESS">InProgress</a-tag>
|
||||
<a-tag color="green" v-else-if="record.workflowNode.status===ECommon_Model_Workflow_Node_Status.DONE">Done</a-tag>
|
||||
<a-tag color="gray" v-if="record.workflowNode.status===ECommon_Model_Workflow_Node_Status.NOTSTART">{{$t("util.notstart")}}</a-tag>
|
||||
<a-tag color="blue" v-else-if="record.workflowNode.status===ECommon_Model_Workflow_Node_Status.INPROGRESS">{{$t("util.inProgress")}}</a-tag>
|
||||
<a-tag color="green" v-else-if="record.workflowNode.status===ECommon_Model_Workflow_Node_Status.DONE">{{$t("util.done")}}</a-tag>
|
||||
</template>
|
||||
<template #operation="{record}">
|
||||
<a-button type="text" @click="onRemoveIssue(record)">
|
||||
@ -110,25 +110,27 @@ import ProjectIssueBind from "../issue/projectIssueBind.vue";
|
||||
import {EClient_EVENTBUS_TYPE, eventBus} from "../../../../common/event/event";
|
||||
import {vDrag} from "../../../../../teamOS/common/directive/drag";
|
||||
import {ECommon_Model_Finder_Shortcut_Type} from "../../../../../../../common/model/finder_item";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectReleaseId:string
|
||||
}>()
|
||||
const {t}=useI18n()
|
||||
const columns=[
|
||||
{
|
||||
title:"Key",
|
||||
slotName:"key"
|
||||
},
|
||||
{
|
||||
title:"Name",
|
||||
title:t("util.name"),
|
||||
slotName: "name"
|
||||
},
|
||||
{
|
||||
title:"Issue Type",
|
||||
title:t("util.issueType"),
|
||||
slotName: "issueType"
|
||||
},
|
||||
{
|
||||
title:"Priority",
|
||||
title:t("util.priority"),
|
||||
slotName: "priority"
|
||||
},
|
||||
{
|
||||
@ -140,11 +142,11 @@ const columns=[
|
||||
slotName: "reporter"
|
||||
},
|
||||
{
|
||||
title:"Status",
|
||||
title:t("util.status"),
|
||||
slotName: "status"
|
||||
},
|
||||
{
|
||||
title:"Operation",
|
||||
title:t("util.operation"),
|
||||
slotName: "operation"
|
||||
},
|
||||
]
|
||||
@ -164,14 +166,14 @@ const getInfo=async ()=>{
|
||||
}
|
||||
}
|
||||
const onRemoveIssue=async (item:DCSType<ICommon_Route_Res_Release_Info_Issue_Item>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to remove this issue?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.removeIssue"))
|
||||
if(ret) {
|
||||
let res=await apiRelease.removeIssue({
|
||||
projectReleaseId:props.projectReleaseId,
|
||||
projectIssueId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("remove success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
getInfo()
|
||||
}
|
||||
}
|
||||
@ -186,13 +188,13 @@ const onEdit=async ()=>{
|
||||
}
|
||||
}
|
||||
const onDelete=async ()=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this release?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteRelease"))
|
||||
if(ret) {
|
||||
let res=await apiRelease.remove({
|
||||
projectReleaseId:info.value.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("delete success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
navigator.pop()
|
||||
}
|
||||
}
|
||||
@ -218,7 +220,7 @@ const onRelease=async ()=>{
|
||||
status:ECommon_Model_Project_Release_Status.RELEASE
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("release success")
|
||||
Message.success(t("tip.releaseSuccess"))
|
||||
getInfo()
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
@ -234,7 +236,7 @@ const onUnRelease=async ()=>{
|
||||
status:ECommon_Model_Project_Release_Status.UNRELEASE
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("unrelease success")
|
||||
Message.success(t("tip.unReleaseSuccess"))
|
||||
getInfo()
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
@ -246,7 +248,7 @@ const onArchive=async ()=>{
|
||||
status:ECommon_Model_Project_Release_Status.ARCHIVED
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("archive success")
|
||||
Message.success(t("tip.archiveSuccess"))
|
||||
getInfo()
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
@ -263,7 +265,7 @@ const onAddIssue=async ()=>{
|
||||
projectIssueId:ret as string
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("add success")
|
||||
Message.success(t("tip.addSuccess"))
|
||||
getInfo()
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<a-collapse :default-active-key="['basic']" accordion>
|
||||
<a-collapse-item header="Basic" key="basic">
|
||||
<a-collapse-item :header="$t('util.basic')" key="basic">
|
||||
<ProjectSettingBasic :project-id="projectId"></ProjectSettingBasic>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="Module" key="module">
|
||||
<a-collapse-item :header="$t('util.module')" key="module">
|
||||
<ModuleList :project-id="projectId"></ModuleList>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="Tag" key="tag">
|
||||
<a-collapse-item :header="$t('util.tag')" key="tag">
|
||||
<LabelList :project-id="projectId"></LabelList>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="Access" key="access">
|
||||
<a-collapse-item :header="$t('util.access')" key="access">
|
||||
<EditProjectAccess :project-id="projectId"></EditProjectAccess>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="Role" key="role">
|
||||
<a-collapse-item :header="$t('util.role')" key="role">
|
||||
<ProjectSettingRole :project-id="projectId"></ProjectSettingRole>
|
||||
</a-collapse-item>
|
||||
<a-collapse-item header="Issue Solution" key="solution">
|
||||
<a-collapse-item :header="$t('util.issueSolution')" key="solution">
|
||||
<ProjectSettingIssueSolution :project-id="projectId"></ProjectSettingIssueSolution>
|
||||
</a-collapse-item>
|
||||
</a-collapse>
|
||||
@ -30,6 +30,7 @@ import LabelList from "../../setting/project/labelList.vue";
|
||||
import EditProjectAccess from "../../setting/project/editProjectAccess.vue";
|
||||
import ProjectSettingRole from "./projectSettingRole.vue";
|
||||
import ProjectSettingIssueSolution from "./projectSettingIssueSolution.vue";
|
||||
import {Err} from "../../../../../../../common/status/error";
|
||||
|
||||
|
||||
const projectId=inject(injectProjectInfo).id;
|
||||
|
@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<a-form ref="eleForm" style="width: 80%" :model="form" @submitSuccess="onSubmit">
|
||||
<a-form-item field="name" label="name" required>
|
||||
<a-form-item field="name" :label="$t('util.name')" required>
|
||||
{{form.name}}
|
||||
</a-form-item>
|
||||
<a-form-item field="keyword" label="keyword" required>
|
||||
<a-form-item field="keyword" :label="$t('util.keyword')" required>
|
||||
{{form.keyword}}
|
||||
</a-form-item>
|
||||
<a-form-item field="description" label="description">
|
||||
<a-form-item field="description" :label="$t('util.description')">
|
||||
<a-textarea v-model="form.description" allow-clear></a-textarea>
|
||||
</a-form-item>
|
||||
<a-form-item label="logo">
|
||||
<a-form-item :label="$t('util.logo')">
|
||||
<Upload types=".png,.jpg,.jpeg,.gif,.bmp,.svg" :default-uri="photo" @upload="onUpload"></Upload>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button html-type="submit" type="primary">Save</a-button>
|
||||
<a-button html-type="submit" type="primary">{{$t("util.save")}}</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
@ -24,6 +24,7 @@ import Upload from "../../../../common/component/upload.vue";
|
||||
import {getCurrentInstance, onBeforeMount, reactive, ref} from "vue";
|
||||
import {apiProject} from "../../../../common/request/request";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectId:string
|
||||
@ -35,6 +36,7 @@ const form = reactive({
|
||||
description: "",
|
||||
})
|
||||
const uploadUriId=ref("")
|
||||
const {t}=useI18n()
|
||||
const onUpload=(id:string)=> {
|
||||
uploadUriId.value=id
|
||||
}
|
||||
@ -63,7 +65,7 @@ const onSubmit=async ()=>{
|
||||
})
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("save success")
|
||||
Message.success(t("tip.saveSuccess"))
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<a-form layout="inline" :model="form" @submitSuccess="onSubmit">
|
||||
<a-form-item label="issue type solution" field="issueTypeSolutionId" required>
|
||||
<a-form-item :label="$t('util.issueSolution')" field="issueTypeSolutionId" required>
|
||||
<a-select v-model="form.issueTypeSolutionId" allow-search>
|
||||
<a-option v-for="item in issueSolutionList" :label="item.name" :value="item.id"></a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button html-type="submit" type="primary">Save</a-button>
|
||||
<a-button html-type="submit" type="primary">{{$t("util.save")}}</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
@ -20,6 +20,7 @@ import {getRootNavigatorRef} from "../../../../../teamOS/common/component/naviga
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import ProjectSettingIssueSolutionConvert
|
||||
from "@/business/controller/app/project/setting/projectSettingIssueSolutionConvert.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectId:string
|
||||
@ -30,9 +31,10 @@ const form=reactive({
|
||||
const currentIssueTypeSolutionId=ref("")
|
||||
const appContext=getCurrentInstance().appContext
|
||||
const root=getRootNavigatorRef()
|
||||
const {t}=useI18n()
|
||||
const issueSolutionList=ref<DCSType<ICommon_Model_Issue_Type_Solution>[]>([])
|
||||
const onSubmit=async ()=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to switch to this issue type solution?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.switchIssueSolution"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.count({
|
||||
projectId:props.projectId
|
||||
@ -44,7 +46,7 @@ const onSubmit=async ()=>{
|
||||
issueTypeSolutionId:form.issueTypeSolutionId
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("bind success")
|
||||
Message.success(t("tip.bindSuccess"))
|
||||
currentIssueTypeSolutionId.value=form.issueTypeSolutionId
|
||||
} else {
|
||||
Message.error(res.msg)
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<a-button @click="onAddRole" type="primary" style="margin-bottom: 10px">Add</a-button>
|
||||
<a-button @click="onAddRole" type="primary" style="margin-bottom: 10px">{{$t("util.add")}}</a-button>
|
||||
<a-table :columns="columns" :data="roleList" :pagination="false">
|
||||
<template #description="{record}">
|
||||
{{record.description}}
|
||||
@ -17,8 +17,8 @@
|
||||
<template #operation="{record}">
|
||||
<template v-if="!record.global">
|
||||
<a-space wrap>
|
||||
<a-button type="primary" size="small" @click="onEditRole(record)">manage</a-button>
|
||||
<a-button status="danger" size="small" @click="onDeleteRole(record)">delete</a-button>
|
||||
<a-button type="primary" size="small" @click="onEditRole(record)">{{$t("util.manage")}}</a-button>
|
||||
<a-button status="danger" size="small" @click="onDeleteRole(record)">{{$t("util.delete")}}</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
@ -34,6 +34,7 @@ import {apiProject} from "../../../../common/request/request";
|
||||
import {Message} from "@arco-design/web-vue";
|
||||
import {getRootNavigatorRef} from "../../../../../teamOS/common/component/navigator/navigator";
|
||||
import EditProjectRole from "../../setting/role/project/editProjectRole.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
projectId:string
|
||||
@ -49,25 +50,26 @@ type RoleItem={
|
||||
global:boolean,
|
||||
permissions:Permission_Base[]
|
||||
}
|
||||
const {t}=useI18n()
|
||||
const columns=[
|
||||
{
|
||||
title:"name",
|
||||
title:t("util.name"),
|
||||
dataIndex:"name"
|
||||
},
|
||||
{
|
||||
title:"description",
|
||||
title:t("util.description"),
|
||||
slotName:"description"
|
||||
},
|
||||
{
|
||||
title:"permission",
|
||||
title:t("util.permission"),
|
||||
slotName:"permission"
|
||||
},
|
||||
{
|
||||
title:"global",
|
||||
title:t("util.global"),
|
||||
slotName: "global"
|
||||
},
|
||||
{
|
||||
title:"operation",
|
||||
title:t("util.operation"),
|
||||
slotName: "operation"
|
||||
}
|
||||
]
|
||||
@ -103,13 +105,13 @@ const onEditRole=async (item:RoleItem) =>{
|
||||
}
|
||||
}
|
||||
const onDeleteRole=async (item:RoleItem)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to delete this role?")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.deleteRole"))
|
||||
if(ret) {
|
||||
let res=await apiProject.removeRole({
|
||||
roleId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("remove success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
listRole()
|
||||
} else {
|
||||
Message.error(res.msg);
|
||||
|
@ -15,22 +15,22 @@
|
||||
<template #split>
|
||||
|
|
||||
</template>
|
||||
<a-statistic title="Project Total" :value="staticInfo?.projectCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.setting.home.settingHome.projectTotal')" :value="staticInfo?.projectCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="Issue Total" :value="staticInfo?.issueCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.setting.home.settingHome.issueTotal')" :value="staticInfo?.issueCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="Wiki Space Total" :value="staticInfo?.wikiSpaceCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.setting.home.settingHome.wikiSpaceTotal')" :value="staticInfo?.wikiSpaceCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="Wiki Item Total" :value="staticInfo?.wikiItemCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.setting.home.settingHome.wikiItemTotal')" :value="staticInfo?.wikiItemCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="User Total" :value="staticInfo?.userCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.setting.home.settingHome.userTotal')" :value="staticInfo?.userCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
<a-statistic title="Team Total" :value="staticInfo?.teamCount" show-group-separator :value-style="{
|
||||
<a-statistic :title="$t('controller.app.setting.home.settingHome.teamTotal')" :value="staticInfo?.teamCount" show-group-separator :value-style="{
|
||||
color:'blue'
|
||||
}"/>
|
||||
</a-space>
|
||||
@ -74,6 +74,7 @@ import {
|
||||
} from 'echarts/components';
|
||||
import {LabelLayout, UniversalTransition} from 'echarts/features';
|
||||
import {CanvasRenderer} from 'echarts/renderers';
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
echarts.use([
|
||||
TitleComponent,
|
||||
@ -89,30 +90,31 @@ echarts.use([
|
||||
|
||||
const projectWithIssueEle=ref(),projectWithUnDoneIssueEle=ref(),wikiSpaceWithWikiItemEle=ref(),teamWithUserEle=ref()
|
||||
let projectWithIssueChart:EChartsType,projectWithUnDoneIssueChart:EChartsType,wikiSpaceWithWikiItemChart:EChartsType,teamWithUserChart:EChartsType
|
||||
const {t}=useI18n()
|
||||
const data = [
|
||||
{
|
||||
id: "statics",
|
||||
name: "Statics",
|
||||
name: t("controller.app.setting.home.settingHome.statics"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "projectWithIssueList",
|
||||
name: "Projects With Issues Chart",
|
||||
name: t("controller.app.setting.home.settingHome.projectWithIssueList"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "projectWithUnDoneIssueList",
|
||||
name: "Project With UnResolved Issues Chart",
|
||||
name: t("controller.app.setting.home.settingHome.projectWithUnDoneIssueList"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "wikiSpaceWithWikiItemList",
|
||||
name: "Wiki Space Chart",
|
||||
name: t("controller.app.setting.home.settingHome.wikiSpaceWithWikiItemList"),
|
||||
data: null
|
||||
},
|
||||
{
|
||||
id: "teamWithUserList",
|
||||
name: "Team Chart",
|
||||
name: t("controller.app.setting.home.settingHome.teamWithUserList"),
|
||||
data: null
|
||||
},
|
||||
]
|
||||
@ -128,6 +130,9 @@ const getInfo=async ()=>{
|
||||
const initCharts=()=>{
|
||||
projectWithIssueChart=echarts.init(projectWithIssueEle.value)
|
||||
projectWithIssueChart.setOption({
|
||||
grid:{
|
||||
left:60
|
||||
},
|
||||
dataset:{
|
||||
source:[
|
||||
["count","name"],
|
||||
@ -143,7 +148,12 @@ const initCharts=()=>{
|
||||
},
|
||||
yAxis: {
|
||||
name:"Project",
|
||||
type: 'category'
|
||||
type: 'category',
|
||||
axisLabel:{
|
||||
show:true,
|
||||
overflow:"breakAll",
|
||||
width:40
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@ -158,6 +168,9 @@ const initCharts=()=>{
|
||||
})
|
||||
projectWithUnDoneIssueChart=echarts.init(projectWithUnDoneIssueEle.value)
|
||||
projectWithUnDoneIssueChart.setOption({
|
||||
grid:{
|
||||
left:60
|
||||
},
|
||||
dataset:{
|
||||
source:[
|
||||
["count","name"],
|
||||
@ -173,7 +186,12 @@ const initCharts=()=>{
|
||||
},
|
||||
yAxis: {
|
||||
name:"Project",
|
||||
type: 'category'
|
||||
type: 'category',
|
||||
axisLabel:{
|
||||
show:true,
|
||||
overflow:"breakAll",
|
||||
width:40
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@ -188,6 +206,9 @@ const initCharts=()=>{
|
||||
})
|
||||
wikiSpaceWithWikiItemChart=echarts.init(wikiSpaceWithWikiItemEle.value)
|
||||
wikiSpaceWithWikiItemChart.setOption({
|
||||
grid:{
|
||||
left:60
|
||||
},
|
||||
dataset:{
|
||||
source:[
|
||||
["count","name"],
|
||||
@ -203,7 +224,12 @@ const initCharts=()=>{
|
||||
},
|
||||
yAxis: {
|
||||
name:"Wiki Space",
|
||||
type: 'category'
|
||||
type: 'category',
|
||||
axisLabel:{
|
||||
show:true,
|
||||
overflow:"breakAll",
|
||||
width:40
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
@ -218,6 +244,9 @@ const initCharts=()=>{
|
||||
})
|
||||
teamWithUserChart=echarts.init(teamWithUserEle.value)
|
||||
teamWithUserChart.setOption({
|
||||
grid:{
|
||||
left:60
|
||||
},
|
||||
dataset:{
|
||||
source:[
|
||||
["count","name"],
|
||||
@ -233,7 +262,12 @@ const initCharts=()=>{
|
||||
},
|
||||
yAxis: {
|
||||
name:"Team",
|
||||
type: 'category'
|
||||
type: 'category',
|
||||
axisLabel:{
|
||||
show:true,
|
||||
overflow:"breakAll",
|
||||
width:50
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<a-form :model="form" style="width: 80%" ref="eleForm">
|
||||
<a-form-item field="workflowNodeId" label="issue type" required>
|
||||
<a-cascader :options="data" v-model="form.workflowNodeId" :field-names="fields" placeholder="please select" allow-search></a-cascader>
|
||||
<a-form-item field="workflowNodeId" :label="$t('util.issueType')" required>
|
||||
<a-cascader :options="data" v-model="form.workflowNodeId" :field-names="fields" :placeholder="$t('placeholder.pleaseSelect')" allow-search></a-cascader>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-form :model="form" style="width: 80%" ref="eleForm">
|
||||
<a-form-item label="fieldTypeId" required>
|
||||
<a-form-item filed="fieldTypeId" :label="$t('util.fieldType')" required>
|
||||
<a-select v-model="form.fieldTypeId">
|
||||
<a-option label="Switch" :value="ECommon_Field_Type.SWITCH"></a-option>
|
||||
<a-option label="Multi Select" :value="ECommon_Field_Type.MULTISELECT"></a-option>
|
||||
@ -13,10 +13,10 @@
|
||||
<a-option label="Date" :value="ECommon_Field_Type.DATE"></a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item label="name" required>
|
||||
<a-form-item field="name" :label="$t('util.name')" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item label="description">
|
||||
<a-form-item field="description" :label="$t('util.description')">
|
||||
<a-textarea v-model="form.description"></a-textarea>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<a-form style="width: 80%" :model="form" ref="eleForm">
|
||||
<a-form-item field="status" label="type" required>
|
||||
<a-form-item field="status" :label="$t('util.type')" required>
|
||||
<a-select v-model="form.status">
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.INPROGRESS">INPROGRESS</a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.DONE">DONE</a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.INPROGRESS">{{$t("util.inProgress")}}</a-option>
|
||||
<a-option :value="ECommon_Model_Workflow_Node_Status.DONE">{{$t("util.done")}}</a-option>
|
||||
</a-select>
|
||||
</a-form-item>
|
||||
<a-form-item field="name" label="name" required>
|
||||
<a-form-item field="name" :label="$t('util.name')" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item field="description" label="description" required>
|
||||
<a-form-item field="description" :label="$t('util.description')" required>
|
||||
<a-textarea v-model="form.description" allow-clear></a-textarea>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div ref="root">
|
||||
<a-space>
|
||||
<a-input-search @search="onSearch" v-model="keyword" style="width: 300px" search-button placeholder="please type project name"></a-input-search>
|
||||
<a-button type="primary" @click="onBind">Bind</a-button>
|
||||
<a-input-search @search="onSearch" v-model="keyword" style="width: 300px" search-button :placeholder="$t('placeholder.typeProjectName')"></a-input-search>
|
||||
<a-button type="primary" @click="onBind">{{$t("util.bind")}}</a-button>
|
||||
</a-space>
|
||||
<a-table style="margin-top: 10px" :columns="columns" :data="data" :pagination="pagination" @pageChange="onPageChange">
|
||||
<template #operation="{record}" v-if="!reserved">
|
||||
<a-button size="small" type="primary" status="danger" @click="onUnBind(record)">Revoke</a-button>
|
||||
<a-button size="small" type="primary" status="danger" @click="onUnBind(record)">{{$t("util.revoke")}}</a-button>
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
@ -21,23 +21,24 @@ import {ICommon_Model_Project} from "../../../../../../../common/model/project";
|
||||
import EditBindProject from "./editBindProject.vue";
|
||||
import ProjectSettingIssueSolutionConvert
|
||||
from "@/business/controller/app/project/setting/projectSettingIssueSolutionConvert.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
|
||||
const props=defineProps<{
|
||||
issueTypeSolutionId:string,
|
||||
reserved:number
|
||||
}>()
|
||||
|
||||
const {t}=useI18n()
|
||||
const columns=[
|
||||
{
|
||||
title:"name",
|
||||
title:t("util.name"),
|
||||
dataIndex:"name"
|
||||
},
|
||||
{
|
||||
title:"description",
|
||||
title:t("util.description"),
|
||||
dataIndex:"description"
|
||||
},
|
||||
{
|
||||
title:"operation",
|
||||
title:t("util.operation"),
|
||||
slotName: "operation"
|
||||
}
|
||||
]
|
||||
@ -80,7 +81,7 @@ const onBind=async ()=>{
|
||||
}
|
||||
}
|
||||
const onUnBind=async (item:DCSType<ICommon_Model_Project>)=>{
|
||||
let ret=await Dialog.confirm(root.value,appContext,"Do you want to unbind this project with this issue type solution")
|
||||
let ret=await Dialog.confirm(root.value,appContext,t("tip.unbindProjectFromIssueSolution"))
|
||||
if(ret) {
|
||||
let res=await apiIssue.count({
|
||||
projectId:item.id
|
||||
@ -91,7 +92,7 @@ const onUnBind=async (item:DCSType<ICommon_Model_Project>)=>{
|
||||
projectId:item.id
|
||||
})
|
||||
if(res?.code==0) {
|
||||
Message.success("remove success")
|
||||
Message.success(t("tip.deleteSuccess"))
|
||||
search(pagination.current)
|
||||
}
|
||||
} else {
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a-form :model="form" ref="eleForm" style="width: 80%" auto-label-width>
|
||||
<a-form-item field="projectId" label="project" required>
|
||||
<a-form-item field="projectId" :label="$t('util.project')" required>
|
||||
<a-select @search="onSearch" v-model="form.projectId" allow-search @change="onChange">
|
||||
<a-option v-for="item in projectList" :value="item.id" :label="item.name"></a-option>
|
||||
</a-select>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<a-form ref="eleForm" :model="form" style="width: 80%">
|
||||
<a-form-item field="name" label="name" required>
|
||||
<a-form-item field="name" :label="$t('util.name')" required>
|
||||
<a-input v-model="form.name"></a-input>
|
||||
</a-form-item>
|
||||
<a-form-item field="description" label="description">
|
||||
<a-form-item field="description" :label="$t('util.description')">
|
||||
<a-textarea v-model="form.description" allow-clear></a-textarea>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user