Amy0104
3 years ago
committed by
GitHub
17 changed files with 1328 additions and 40 deletions
@ -0,0 +1,332 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { defineComponent, PropType, toRefs, watch } from 'vue' |
||||
import { |
||||
NButton, |
||||
NSpin, |
||||
NForm, |
||||
NFormItem, |
||||
NSelect, |
||||
NInput, |
||||
NInputNumber, |
||||
NRadioGroup, |
||||
NRadio, |
||||
NSpace |
||||
} from 'naive-ui' |
||||
import Modal from '@/components/modal' |
||||
import { useI18n } from 'vue-i18n' |
||||
import { useForm, datasourceTypeList } from './use-form' |
||||
import { useDetail } from './use-detail' |
||||
|
||||
const props = { |
||||
show: { |
||||
type: Boolean as PropType<boolean>, |
||||
default: false |
||||
}, |
||||
id: { |
||||
type: Number as PropType<number> |
||||
} |
||||
} |
||||
|
||||
const DetailModal = defineComponent({ |
||||
name: 'DetailModal', |
||||
props, |
||||
emits: ['cancel', 'update'], |
||||
setup(props, ctx) { |
||||
const { t } = useI18n() |
||||
|
||||
const { |
||||
state, |
||||
changeType, |
||||
changePort, |
||||
resetFieldsValue, |
||||
setFieldsValue, |
||||
getFieldsValue |
||||
} = useForm(props.id) |
||||
|
||||
const { status, queryById, testConnect, createOrUpdate } = |
||||
useDetail(getFieldsValue) |
||||
|
||||
const onCancel = () => { |
||||
resetFieldsValue() |
||||
ctx.emit('cancel') |
||||
} |
||||
|
||||
const onSubmit = async () => { |
||||
await state.detailFormRef.validate() |
||||
const res = await createOrUpdate(props.id) |
||||
if (res) { |
||||
onCancel() |
||||
ctx.emit('update') |
||||
} |
||||
} |
||||
|
||||
const onTest = async () => { |
||||
await state.detailFormRef.validate() |
||||
testConnect() |
||||
} |
||||
|
||||
const onChangeType = changeType |
||||
const onChangePort = changePort |
||||
|
||||
watch( |
||||
() => props.show, |
||||
async () => { |
||||
props.show && props.id && setFieldsValue(await queryById(props.id)) |
||||
} |
||||
) |
||||
|
||||
return { |
||||
t, |
||||
...toRefs(state), |
||||
...toRefs(status), |
||||
onChangeType, |
||||
onChangePort, |
||||
onSubmit, |
||||
onTest, |
||||
onCancel |
||||
} |
||||
}, |
||||
render() { |
||||
const { |
||||
show, |
||||
id, |
||||
t, |
||||
detailForm, |
||||
rules, |
||||
requiredDataBase, |
||||
showConnectType, |
||||
showPrincipal, |
||||
loading, |
||||
saving, |
||||
testing, |
||||
onChangeType, |
||||
onChangePort, |
||||
onCancel, |
||||
onTest, |
||||
onSubmit |
||||
} = this |
||||
return ( |
||||
<Modal |
||||
show={show} |
||||
title={`${t(id ? 'datasource.edit' : 'datasource.create')}${t( |
||||
'datasource.datasource' |
||||
)}`}
|
||||
onConfirm={onSubmit} |
||||
confirmLoading={saving || loading} |
||||
onCancel={onCancel} |
||||
> |
||||
{{ |
||||
default: () => ( |
||||
<NSpin show={loading}> |
||||
<NForm |
||||
rules={rules} |
||||
ref='detailFormRef' |
||||
require-mark-placement='left' |
||||
label-placement='left' |
||||
label-width={180} |
||||
label-align='right' |
||||
> |
||||
<NFormItem |
||||
label={t('datasource.datasource')} |
||||
path='type' |
||||
show-require-mark |
||||
> |
||||
<NSelect |
||||
v-model={[detailForm.type, 'value']} |
||||
options={datasourceTypeList} |
||||
disabled={!!id} |
||||
on-update:value={onChangeType} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.datasource_name')} |
||||
path='name' |
||||
show-require-mark |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.name, 'value']} |
||||
maxlength={60} |
||||
placeholder={t('datasource.datasource_name_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem label={t('datasource.description')} path='note'> |
||||
<NInput |
||||
v-model={[detailForm.note, 'value']} |
||||
type='textarea' |
||||
placeholder={t('datasource.description_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.ip')} |
||||
path='host' |
||||
show-require-mark |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.host, 'value']} |
||||
type='text' |
||||
maxlength={255} |
||||
placeholder={t('datasource.ip_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.port')} |
||||
path='port' |
||||
show-require-mark |
||||
> |
||||
<NInputNumber |
||||
v-model={[detailForm.port, 'value']} |
||||
show-button={false} |
||||
placeholder={t('datasource.port_tips')} |
||||
on-blur={onChangePort} |
||||
style={{ width: '100%' }} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
v-show={showPrincipal} |
||||
label='Principal' |
||||
path='principal' |
||||
show-require-mark |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.principal, 'value']} |
||||
type='text' |
||||
placeholder={t('datasource.principal_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
v-show={showPrincipal} |
||||
label='krb5.conf' |
||||
path='javaSecurityKrb5Conf' |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.javaSecurityKrb5Conf, 'value']} |
||||
type='text' |
||||
placeholder={t('datasource.krb5_conf_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
v-show={showPrincipal} |
||||
label='keytab.username' |
||||
path='loginUserKeytabUsername' |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.loginUserKeytabUsername, 'value']} |
||||
type='text' |
||||
placeholder={t('datasource.keytab_username_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
v-show={showPrincipal} |
||||
label='keytab.path' |
||||
path='loginUserKeytabPath' |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.loginUserKeytabPath, 'value']} |
||||
type='text' |
||||
placeholder={t('datasource.keytab_path_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.user_name')} |
||||
path='userName' |
||||
show-require-mark |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.userName, 'value']} |
||||
type='text' |
||||
maxlength={60} |
||||
placeholder={t('datasource.user_name_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.user_password')} |
||||
path='password' |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.password, 'value']} |
||||
type='password' |
||||
placeholder={t('datasource.user_password_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.database_name')} |
||||
path='database' |
||||
show-require-mark={requiredDataBase} |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.database, 'value']} |
||||
type='text' |
||||
maxlength={60} |
||||
placeholder={t('datasource.database_name_tips')} |
||||
/> |
||||
</NFormItem> |
||||
<NFormItem |
||||
v-show={showConnectType} |
||||
label={t('datasource.oracle_connect_type')} |
||||
path='connectType' |
||||
show-require-mark |
||||
> |
||||
<NRadioGroup v-model={[detailForm.connectType, 'value']}> |
||||
<NSpace> |
||||
<NRadio value='ORACLE_SERVICE_NAME'> |
||||
{t('datasource.oracle_service_name')} |
||||
</NRadio> |
||||
<NRadio value='ORACLE_SID'> |
||||
{t('datasource.oracle_sid')} |
||||
</NRadio> |
||||
</NSpace> |
||||
</NRadioGroup> |
||||
</NFormItem> |
||||
<NFormItem |
||||
label={t('datasource.jdbc_connect_parameters')} |
||||
path='other' |
||||
> |
||||
<NInput |
||||
v-model={[detailForm.other, 'value']} |
||||
type='textarea' |
||||
autosize={{ |
||||
minRows: 2 |
||||
}} |
||||
placeholder={`${t( |
||||
'datasource.format_tips' |
||||
)} {"key1":"value1","key2":"value2"...} ${t( |
||||
'datasource.connection_parameter' |
||||
)}`}
|
||||
/> |
||||
</NFormItem> |
||||
</NForm> |
||||
</NSpin> |
||||
), |
||||
'btn-middle': () => ( |
||||
<NButton |
||||
type='primary' |
||||
size='small' |
||||
onClick={onTest} |
||||
loading={testing || loading} |
||||
> |
||||
{t('datasource.test_connect')} |
||||
</NButton> |
||||
) |
||||
}} |
||||
</Modal> |
||||
) |
||||
} |
||||
}) |
||||
|
||||
export default DetailModal |
@ -0,0 +1,32 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
.conditions { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
} |
||||
.conditions-search-input { |
||||
width: 250px; |
||||
} |
||||
.pagination { |
||||
margin-top: 20px; |
||||
justify-content: center; |
||||
} |
||||
.mt-8 { |
||||
margin-top: 8px; |
||||
} |
@ -0,0 +1,150 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { defineComponent, onMounted, ref, toRefs } from 'vue' |
||||
import { |
||||
NButton, |
||||
NInput, |
||||
NIcon, |
||||
NDataTable, |
||||
NPagination, |
||||
NSpace |
||||
} from 'naive-ui' |
||||
import Card from '@/components/card' |
||||
import DetailModal from './detail' |
||||
import { SearchOutlined } from '@vicons/antd' |
||||
import { useI18n } from 'vue-i18n' |
||||
import { useColumns } from './use-columns' |
||||
import { useTable } from './use-table' |
||||
import styles from './index.module.scss' |
||||
|
||||
const list = defineComponent({ |
||||
name: 'list', |
||||
setup() { |
||||
const { t } = useI18n() |
||||
let showDetailModal = ref(false) |
||||
let selectId = ref() |
||||
|
||||
const { columnsRef } = useColumns((id: number, type: 'edit' | 'delete') => { |
||||
if (type === 'edit') { |
||||
showDetailModal.value = true |
||||
selectId.value = id |
||||
} else { |
||||
deleteRecord(id) |
||||
} |
||||
}) |
||||
|
||||
const { data, changePage, changePageSize, deleteRecord, updateList } = |
||||
useTable() |
||||
|
||||
const onCreate = () => { |
||||
selectId.value = null |
||||
showDetailModal.value = true |
||||
} |
||||
|
||||
onMounted(() => { |
||||
changePage(1) |
||||
}) |
||||
|
||||
return { |
||||
t, |
||||
showDetailModal, |
||||
id: selectId, |
||||
columnsRef, |
||||
...toRefs(data), |
||||
changePage, |
||||
changePageSize, |
||||
onCreate, |
||||
onUpdatedList: updateList |
||||
} |
||||
}, |
||||
render() { |
||||
const { |
||||
t, |
||||
id, |
||||
showDetailModal, |
||||
columnsRef, |
||||
list, |
||||
page, |
||||
pageSize, |
||||
itemCount, |
||||
loading, |
||||
changePage, |
||||
changePageSize, |
||||
onCreate, |
||||
onUpdatedList |
||||
} = this |
||||
|
||||
return ( |
||||
<> |
||||
<Card title=''> |
||||
{{ |
||||
default: () => ( |
||||
<div class={styles['conditions']}> |
||||
<NButton onClick={onCreate} type='primary'>{`${t( |
||||
'datasource.create_datasource' |
||||
)}`}</NButton>
|
||||
|
||||
<NSpace |
||||
class={styles['conditions-search']} |
||||
justify='end' |
||||
wrap={false} |
||||
> |
||||
<div class={styles['conditions-search-input']}> |
||||
<NInput |
||||
v-model={[this.searchVal, 'value']} |
||||
placeholder={`${t('datasource.search_input_tips')}`} |
||||
/> |
||||
</div> |
||||
<NButton type='primary' onClick={onUpdatedList}> |
||||
<NIcon> |
||||
<SearchOutlined /> |
||||
</NIcon> |
||||
</NButton> |
||||
</NSpace> |
||||
</div> |
||||
) |
||||
}} |
||||
</Card> |
||||
<Card title='' class={styles['mt-8']}> |
||||
<NDataTable |
||||
columns={columnsRef} |
||||
data={list} |
||||
loading={loading} |
||||
striped |
||||
/> |
||||
<NPagination |
||||
page={page} |
||||
page-size={pageSize} |
||||
item-count={itemCount} |
||||
show-quick-jumper |
||||
class={styles['pagination']} |
||||
on-update:page={changePage} |
||||
on-update:page-size={changePageSize} |
||||
/> |
||||
</Card> |
||||
<DetailModal |
||||
show={showDetailModal} |
||||
id={id} |
||||
onCancel={() => void (this.showDetailModal = false)} |
||||
onUpdate={onUpdatedList} |
||||
/> |
||||
</> |
||||
) |
||||
} |
||||
}) |
||||
export default list |
@ -0,0 +1,26 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
.json-highlight { |
||||
display: block; |
||||
line-height: 1.5; |
||||
font-size: 12px; |
||||
padding: 5px; |
||||
} |
||||
.line { |
||||
padding-left: 8px; |
||||
} |
@ -0,0 +1,67 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { defineComponent, PropType, h } from 'vue' |
||||
import { NText } from 'naive-ui' |
||||
import { isBoolean, isNumber, isPlainObject } from 'lodash' |
||||
import styles from './json-highlight.module.scss' |
||||
|
||||
const props = { |
||||
json: { |
||||
type: String as PropType<string>, |
||||
default: '' |
||||
} |
||||
} |
||||
|
||||
const JsonHighlight = defineComponent({ |
||||
name: 'JsonHighlight', |
||||
props, |
||||
render() { |
||||
return ( |
||||
<pre class={styles['json-highlight']}>{syntaxHighlight(this.json)}</pre> |
||||
) |
||||
} |
||||
}) |
||||
|
||||
const syntaxHighlight = (json: string) => { |
||||
if (!isPlainObject(JSON.parse(json))) return '' |
||||
const lines = [<NText v-html='{'></NText>] |
||||
const entries = Object.entries(JSON.parse(json)) |
||||
for (let i = 0, len = entries.length; i < len; i++) { |
||||
const [key, value] = entries[i] |
||||
let type: string = '' |
||||
if (isBoolean(value) || value === null) { |
||||
type = 'info' |
||||
} else if (isNumber(value)) { |
||||
type = 'warning' |
||||
} else { |
||||
type = 'success' |
||||
} |
||||
lines.push( |
||||
<NText tag='div' class={styles['line']}> |
||||
<NText type='error'>"{key}": </NText> |
||||
<NText type={type}> |
||||
"{value}"{i !== len - 1 ? ',' : ''} |
||||
</NText> |
||||
</NText> |
||||
) |
||||
} |
||||
lines.push(<NText v-html='}'></NText>) |
||||
return lines |
||||
} |
||||
|
||||
export default JsonHighlight |
@ -0,0 +1,47 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import type { |
||||
IDataSource, |
||||
IDataBase |
||||
} from '@/service/modules/data-source/types' |
||||
import type { TableColumns } from 'naive-ui/es/data-table/src/interface' |
||||
import type { SelectBaseOption } from 'naive-ui/es/select/src/interface' |
||||
|
||||
interface IDataSourceDetail extends Omit<IDataSource, 'other'> { |
||||
other?: string |
||||
} |
||||
|
||||
interface IDataBaseOption extends SelectBaseOption { |
||||
label: string |
||||
value: string |
||||
defaultPort: number |
||||
previousPort?: number |
||||
} |
||||
|
||||
type IDataBaseOptionKeys = { |
||||
[key in IDataBase]: IDataBaseOption |
||||
} |
||||
|
||||
export { |
||||
IDataSource, |
||||
IDataSourceDetail, |
||||
IDataBase, |
||||
IDataBaseOption, |
||||
IDataBaseOptionKeys, |
||||
TableColumns |
||||
} |
@ -0,0 +1,136 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { h } from 'vue' |
||||
import { useI18n } from 'vue-i18n' |
||||
import { NPopover, NButton, NIcon, NPopconfirm, NSpace } from 'naive-ui' |
||||
import { EditOutlined, DeleteOutlined } from '@vicons/antd' |
||||
import JsonHighlight from './json-highlight' |
||||
import styles from './index.module.scss' |
||||
import { TableColumns } from './types' |
||||
|
||||
export function useColumns(onCallback: Function) { |
||||
const { t } = useI18n() |
||||
|
||||
const columnsRef: TableColumns = [ |
||||
{ |
||||
title: t('datasource.serial_number'), |
||||
key: 'index', |
||||
render: (rowData, rowIndex) => rowIndex + 1 |
||||
}, |
||||
{ |
||||
title: t('datasource.datasource_name'), |
||||
key: 'name' |
||||
}, |
||||
{ |
||||
title: t('datasource.datasource_user_name'), |
||||
key: 'userName' |
||||
}, |
||||
{ |
||||
title: t('datasource.datasource_type'), |
||||
key: 'type' |
||||
}, |
||||
{ |
||||
title: t('datasource.datasource_parameter'), |
||||
key: 'parameter', |
||||
render: (rowData) => { |
||||
return h( |
||||
NPopover, |
||||
{ trigger: 'click' }, |
||||
{ |
||||
trigger: () => |
||||
h( |
||||
NButton, |
||||
{ |
||||
quaternary: true, |
||||
type: 'primary' |
||||
}, |
||||
{ |
||||
default: () => t('datasource.click_to_view') |
||||
} |
||||
), |
||||
default: () => |
||||
h(JsonHighlight, { json: rowData.connectionParams }, null) |
||||
} |
||||
) |
||||
} |
||||
}, |
||||
{ |
||||
title: t('datasource.description'), |
||||
key: 'note' |
||||
}, |
||||
{ |
||||
title: t('datasource.create_time'), |
||||
key: 'createTime' |
||||
}, |
||||
{ |
||||
title: t('datasource.update_time'), |
||||
key: 'updateTime' |
||||
}, |
||||
{ |
||||
title: t('datasource.operation'), |
||||
key: 'operation', |
||||
width: 150, |
||||
render: (rowData, rowIndex) => { |
||||
return h(NSpace, null, { |
||||
default: () => [ |
||||
h( |
||||
NButton, |
||||
{ |
||||
circle: true, |
||||
class: styles['mr-10'], |
||||
type: 'info', |
||||
onClick: () => void onCallback(rowData.id, 'edit') |
||||
}, |
||||
{ |
||||
default: () => |
||||
h(NIcon, null, { default: () => h(EditOutlined) }) |
||||
} |
||||
), |
||||
h( |
||||
NPopconfirm, |
||||
{ |
||||
onPositiveClick: () => void onCallback(rowData.id, 'delete'), |
||||
negativeText: t('datasource.cancel'), |
||||
positiveText: t('datasource.confirm') |
||||
}, |
||||
{ |
||||
trigger: () => |
||||
h( |
||||
NButton, |
||||
{ |
||||
circle: true, |
||||
type: 'error' |
||||
}, |
||||
{ |
||||
default: () => |
||||
h(NIcon, null, { default: () => h(DeleteOutlined) }) |
||||
} |
||||
), |
||||
default: () => t('datasource.delete') |
||||
} |
||||
) |
||||
] |
||||
}) |
||||
} |
||||
} |
||||
] |
||||
|
||||
return { |
||||
columnsRef |
||||
} |
||||
} |
@ -0,0 +1,103 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { reactive } from 'vue' |
||||
import { |
||||
queryDataSource, |
||||
createDataSource, |
||||
updateDataSource, |
||||
connectDataSource, |
||||
verifyDataSourceName |
||||
} from '@/service/modules/data-source' |
||||
import { useI18n } from 'vue-i18n' |
||||
import type { IDataSource } from './types' |
||||
|
||||
export function useDetail(getFieldsValue: Function) { |
||||
const { t } = useI18n() |
||||
const status = reactive({ |
||||
saving: false, |
||||
testing: false, |
||||
loading: false |
||||
}) |
||||
|
||||
let PREV_NAME: string |
||||
|
||||
const formatParams = (): IDataSource => { |
||||
const values = getFieldsValue() |
||||
return { |
||||
...values, |
||||
other: values.other ? JSON.parse(values.other) : null |
||||
} |
||||
} |
||||
|
||||
const queryById = async (id: number) => { |
||||
if (status.loading) return {} |
||||
status.loading = true |
||||
try { |
||||
const dataSourceRes = await queryDataSource(id) |
||||
status.loading = false |
||||
PREV_NAME = dataSourceRes.name |
||||
return dataSourceRes |
||||
} catch (e) { |
||||
window.$message.error((e as Error).message) |
||||
status.loading = false |
||||
return {} |
||||
} |
||||
} |
||||
|
||||
const testConnect = async () => { |
||||
if (status.testing) return |
||||
status.testing = true |
||||
try { |
||||
const res = await connectDataSource(formatParams()) |
||||
window.$message.success( |
||||
res |
||||
? res.msg |
||||
: `${t('datasource.test_connect')} ${t('datasource.success')}` |
||||
) |
||||
status.testing = false |
||||
} catch (e) { |
||||
window.$message.error((e as Error).message) |
||||
status.testing = false |
||||
} |
||||
} |
||||
|
||||
const createOrUpdate = async (id?: number) => { |
||||
const values = getFieldsValue() |
||||
if (status.saving || !values.name) return false |
||||
status.saving = true |
||||
|
||||
try { |
||||
if (PREV_NAME !== values.name) { |
||||
await verifyDataSourceName({ name: values.name }) |
||||
} |
||||
|
||||
id |
||||
? await updateDataSource(formatParams(), id) |
||||
: await createDataSource(formatParams()) |
||||
|
||||
status.saving = false |
||||
return true |
||||
} catch (e) { |
||||
window.$message.error((e as Error).message) |
||||
status.saving = false |
||||
return false |
||||
} |
||||
} |
||||
|
||||
return { status, queryById, testConnect, createOrUpdate } |
||||
} |
@ -0,0 +1,209 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { reactive, ref } from 'vue' |
||||
import { useI18n } from 'vue-i18n' |
||||
import { getKerberosStartupState } from '@/service/modules/data-source' |
||||
import type { FormRules } from 'naive-ui' |
||||
import type { |
||||
IDataSourceDetail, |
||||
IDataBase, |
||||
IDataBaseOption, |
||||
IDataBaseOptionKeys |
||||
} from './types' |
||||
|
||||
export function useForm(id?: number) { |
||||
const { t } = useI18n() |
||||
|
||||
const initialValues = { |
||||
type: 'MYSQL', |
||||
name: '', |
||||
note: '', |
||||
host: '', |
||||
port: datasourceType['MYSQL'].defaultPort, |
||||
principal: '', |
||||
javaSecurityKrb5Conf: '', |
||||
loginUserKeytabUsername: '', |
||||
loginUserKeytabPath: '', |
||||
userName: '', |
||||
password: '', |
||||
database: '', |
||||
connectType: '', |
||||
other: '' |
||||
} as IDataSourceDetail |
||||
|
||||
const state = reactive({ |
||||
detailFormRef: ref(), |
||||
detailForm: { ...initialValues }, |
||||
requiredDataBase: true, |
||||
showConnectType: false, |
||||
showPrincipal: false, |
||||
rules: { |
||||
name: { |
||||
trigger: ['input'], |
||||
validator() { |
||||
if (!state.detailForm.name) { |
||||
return new Error(t('datasource.datasource_name_tips')) |
||||
} |
||||
} |
||||
}, |
||||
host: { |
||||
trigger: ['input'], |
||||
validator() { |
||||
if (!state.detailForm.host) { |
||||
return new Error(t('datasource.ip_tips')) |
||||
} |
||||
} |
||||
}, |
||||
port: { |
||||
trigger: ['input'], |
||||
validator() { |
||||
if (!state.detailForm.port) { |
||||
return new Error(t('datasource.port_tips')) |
||||
} |
||||
} |
||||
}, |
||||
principal: { |
||||
trigger: ['input'], |
||||
validator() { |
||||
if (!state.detailForm.principal && state.showPrincipal) { |
||||
return new Error(t('datasource.principal_tips')) |
||||
} |
||||
} |
||||
}, |
||||
userName: { |
||||
trigger: ['input'], |
||||
validator() { |
||||
if (!state.detailForm.userName) { |
||||
return new Error(t('datasource.user_name_tips')) |
||||
} |
||||
} |
||||
}, |
||||
database: { |
||||
trigger: ['input'], |
||||
validator() { |
||||
if (!state.detailForm.database && state.requiredDataBase) { |
||||
return new Error(t('datasource.database_name_tips')) |
||||
} |
||||
} |
||||
}, |
||||
connectType: { |
||||
trigger: ['update'], |
||||
validator() { |
||||
if (!state.detailForm.connectType && state.showConnectType) { |
||||
return new Error(t('datasource.oracle_connect_type_tips')) |
||||
} |
||||
} |
||||
} |
||||
} as FormRules |
||||
}) |
||||
|
||||
const changeType = async (type: IDataBase, options: IDataBaseOption) => { |
||||
state.detailForm.port = options.previousPort || options.defaultPort |
||||
state.detailForm.type = type |
||||
|
||||
if (type === 'ORACLE' && !id) { |
||||
state.detailForm.connectType = 'ORACLE_SERVICE_NAME' |
||||
} |
||||
state.requiredDataBase = type !== 'POSTGRESQL' |
||||
state.showConnectType = type === 'ORACLE' |
||||
|
||||
if (type === 'HIVE' || type === 'SPARK') { |
||||
try { |
||||
state.showPrincipal = await getKerberosStartupState() |
||||
} catch (e) { |
||||
window.$message.error((e as Error).message) |
||||
} |
||||
} else { |
||||
state.showPrincipal = false |
||||
} |
||||
} |
||||
|
||||
const changePort = async () => { |
||||
if (!state.detailForm.type) return |
||||
const currentDataBaseOption = datasourceType[state.detailForm.type] |
||||
currentDataBaseOption.previousPort = state.detailForm.port |
||||
} |
||||
|
||||
const resetFieldsValue = () => { |
||||
state.detailForm = { ...initialValues } |
||||
} |
||||
const setFieldsValue = (values: object) => { |
||||
state.detailForm = { ...state.detailForm, ...values } |
||||
} |
||||
const getFieldsValue = () => state.detailForm |
||||
|
||||
return { |
||||
state, |
||||
changeType, |
||||
changePort, |
||||
resetFieldsValue, |
||||
setFieldsValue, |
||||
getFieldsValue |
||||
} |
||||
} |
||||
|
||||
const datasourceType: IDataBaseOptionKeys = { |
||||
MYSQL: { |
||||
value: 'MYSQL', |
||||
label: 'MYSQL', |
||||
defaultPort: 3306 |
||||
}, |
||||
POSTGRESQL: { |
||||
value: 'POSTGRESQL', |
||||
label: 'POSTGRESQL', |
||||
defaultPort: 5432 |
||||
}, |
||||
HIVE: { |
||||
value: 'HIVE', |
||||
label: 'HIVE/IMPALA', |
||||
defaultPort: 10000 |
||||
}, |
||||
SPARK: { |
||||
value: 'SPARK', |
||||
label: 'SPARK', |
||||
defaultPort: 10015 |
||||
}, |
||||
CLICKHOUSE: { |
||||
value: 'CLICKHOUSE', |
||||
label: 'CLICKHOUSE', |
||||
defaultPort: 8123 |
||||
}, |
||||
ORACLE: { |
||||
value: 'ORACLE', |
||||
label: 'ORACLE', |
||||
defaultPort: 1521 |
||||
}, |
||||
SQLSERVER: { |
||||
value: 'SQLSERVER', |
||||
label: 'SQLSERVER', |
||||
defaultPort: 1433 |
||||
}, |
||||
DB2: { |
||||
value: 'DB2', |
||||
label: 'DB2', |
||||
defaultPort: 50000 |
||||
}, |
||||
PRESTO: { |
||||
value: 'PRESTO', |
||||
label: 'PRESTO', |
||||
defaultPort: 8080 |
||||
} |
||||
} |
||||
|
||||
export const datasourceTypeList: IDataBaseOption[] = |
||||
Object.values(datasourceType) |
@ -0,0 +1,82 @@
|
||||
/* |
||||
* Licensed to the Apache Software Foundation (ASF) under one or more |
||||
* contributor license agreements. See the NOTICE file distributed with |
||||
* this work for additional information regarding copyright ownership. |
||||
* The ASF licenses this file to You under the Apache License, Version 2.0 |
||||
* (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
import { reactive } from 'vue' |
||||
import { |
||||
queryDataSourceListPaging, |
||||
deleteDataSource |
||||
} from '@/service/modules/data-source' |
||||
|
||||
export function useTable() { |
||||
const data = reactive({ |
||||
page: 1, |
||||
pageSize: 10, |
||||
itemCount: 0, |
||||
searchVal: '', |
||||
list: [], |
||||
loading: false |
||||
}) |
||||
|
||||
const getList = async () => { |
||||
if (data.loading) return |
||||
data.loading = true |
||||
|
||||
try { |
||||
const listRes = await queryDataSourceListPaging({ |
||||
pageNo: data.page, |
||||
pageSize: data.pageSize, |
||||
searchVal: data.searchVal |
||||
}) |
||||
data.loading = false |
||||
data.list = listRes.totalList |
||||
data.itemCount = listRes.total |
||||
} catch (e) { |
||||
window.$message.error((e as Error).message) |
||||
data.loading = false |
||||
data.list = [] |
||||
} |
||||
} |
||||
|
||||
const updateList = () => { |
||||
if (data.list.length === 1 && data.page > 1) { |
||||
--data.page |
||||
} |
||||
getList() |
||||
} |
||||
|
||||
const deleteRecord = async (id: number) => { |
||||
try { |
||||
const res = await deleteDataSource(id) |
||||
updateList() |
||||
} catch (e) { |
||||
window.$message.error((e as Error).message) |
||||
} |
||||
} |
||||
|
||||
const changePage = (page: number) => { |
||||
data.page = page |
||||
getList() |
||||
} |
||||
|
||||
const changePageSize = (pageSize: number) => { |
||||
data.page = 1 |
||||
data.pageSize = pageSize |
||||
getList() |
||||
} |
||||
|
||||
return { data, changePage, changePageSize, deleteRecord, updateList } |
||||
} |
Loading…
Reference in new issue