Browse Source
* add file * fix form style * fix menu key not init bug * add license header * fix review question * delete jquery * modify conditions place * use pagination components instead of pagination attr of tables. * fixed table column width * delete card component title required attr * add table style3.0.0/version-upgrade
Devosend
3 years ago
committed by
GitHub
41 changed files with 2488 additions and 34 deletions
@ -0,0 +1,31 @@ |
|||||||
|
/* |
||||||
|
* 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-model { |
||||||
|
display: flex; |
||||||
|
justify-content: space-between; |
||||||
|
align-items: center; |
||||||
|
margin: 10px 0; |
||||||
|
.right { |
||||||
|
> .form-box { |
||||||
|
.list { |
||||||
|
float: right; |
||||||
|
margin: 3px 0 3px 4px; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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 _ from 'lodash' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import { defineComponent, ref } from 'vue' |
||||||
|
import { SearchOutlined } from '@vicons/antd' |
||||||
|
import { NButton, NIcon, NInput, NSpace } from 'naive-ui' |
||||||
|
import Card from '@/components/card' |
||||||
|
import styles from './index.module.scss' |
||||||
|
|
||||||
|
const Conditions = defineComponent({ |
||||||
|
name: 'Conditions', |
||||||
|
emits: ['conditions'], |
||||||
|
setup(props, ctx) { |
||||||
|
const searchVal = ref() |
||||||
|
const handleConditions = () => { |
||||||
|
ctx.emit('conditions', _.trim(searchVal.value)) |
||||||
|
} |
||||||
|
|
||||||
|
return { searchVal, handleConditions } |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
const { $slots, handleConditions } = this |
||||||
|
return ( |
||||||
|
<Card style={{ marginBottom: '5px' }}> |
||||||
|
<div class={styles['conditions-model']}> |
||||||
|
<NSpace>{$slots}</NSpace> |
||||||
|
<div class={styles.right}> |
||||||
|
<div class={styles['form-box']}> |
||||||
|
<div class={styles.list}> |
||||||
|
<NButton onClick={handleConditions}> |
||||||
|
<NIcon> |
||||||
|
<SearchOutlined /> |
||||||
|
</NIcon> |
||||||
|
</NButton> |
||||||
|
</div> |
||||||
|
<div class={styles.list}> |
||||||
|
<NInput |
||||||
|
placeholder={t('resource.file.enter_keyword_tips')} |
||||||
|
v-model={[this.searchVal, 'value']} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</Card> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
||||||
|
|
||||||
|
export default Conditions |
@ -0,0 +1,121 @@ |
|||||||
|
/* |
||||||
|
* 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, |
||||||
|
onUnmounted, |
||||||
|
PropType, |
||||||
|
nextTick, |
||||||
|
ref, |
||||||
|
watch, |
||||||
|
} from 'vue' |
||||||
|
import * as monaco from 'monaco-editor' |
||||||
|
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' |
||||||
|
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' |
||||||
|
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' |
||||||
|
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' |
||||||
|
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' |
||||||
|
|
||||||
|
const props = { |
||||||
|
modelValue: { |
||||||
|
type: String as PropType<string>, |
||||||
|
default: '', |
||||||
|
}, |
||||||
|
language: { |
||||||
|
type: String as PropType<string>, |
||||||
|
default: 'shell', |
||||||
|
}, |
||||||
|
readOnly: { |
||||||
|
type: Boolean as PropType<boolean>, |
||||||
|
default: false, |
||||||
|
}, |
||||||
|
options: { |
||||||
|
type: Object, |
||||||
|
default: () => {}, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
window.MonacoEnvironment = { |
||||||
|
getWorker(_: any, label: string) { |
||||||
|
if (label === 'json') { |
||||||
|
return new jsonWorker() |
||||||
|
} |
||||||
|
if (['css', 'scss', 'less'].includes(label)) { |
||||||
|
return new cssWorker() |
||||||
|
} |
||||||
|
if (['html', 'handlebars', 'razor'].includes(label)) { |
||||||
|
return new htmlWorker() |
||||||
|
} |
||||||
|
if (['typescript', 'javascript'].includes(label)) { |
||||||
|
return new tsWorker() |
||||||
|
} |
||||||
|
return new editorWorker() |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'MonacoEditor', |
||||||
|
props, |
||||||
|
setup(props) { |
||||||
|
let editor = null as monaco.editor.IStandaloneCodeEditor | null |
||||||
|
const content = ref() |
||||||
|
const getValue = () => editor?.getValue() |
||||||
|
|
||||||
|
watch( |
||||||
|
() => props.modelValue, |
||||||
|
(val) => { |
||||||
|
if (val !== getValue()) { |
||||||
|
editor?.setValue(val) |
||||||
|
} |
||||||
|
}, |
||||||
|
) |
||||||
|
|
||||||
|
onMounted(async () => { |
||||||
|
content.value = props.modelValue |
||||||
|
|
||||||
|
await nextTick() |
||||||
|
const dom = document.getElementById('monaco-container') |
||||||
|
if (dom) { |
||||||
|
editor = monaco.editor.create(dom, props.options, { |
||||||
|
value: props.modelValue, |
||||||
|
language: props.language, |
||||||
|
readOnly: props.readOnly, |
||||||
|
automaticLayout: true, |
||||||
|
}) |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
onUnmounted(() => { |
||||||
|
editor?.dispose() |
||||||
|
}) |
||||||
|
|
||||||
|
return { getValue } |
||||||
|
}, |
||||||
|
render() { |
||||||
|
return ( |
||||||
|
<div |
||||||
|
id='monaco-container' |
||||||
|
style={{ |
||||||
|
height: '300px', |
||||||
|
border: '1px solid #eee', |
||||||
|
}} |
||||||
|
></div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,44 @@ |
|||||||
|
/* |
||||||
|
* 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 { defineStore } from 'pinia' |
||||||
|
import type { FileState } from '@/store/file/types' |
||||||
|
|
||||||
|
export const useFileStore = defineStore({ |
||||||
|
id: 'file', |
||||||
|
state: (): FileState => ({ |
||||||
|
file: '', |
||||||
|
currentDir: '/', |
||||||
|
}), |
||||||
|
persist: true, |
||||||
|
getters: { |
||||||
|
getFileInfo(): string { |
||||||
|
return this.file |
||||||
|
}, |
||||||
|
getCurrentDir(): string { |
||||||
|
return this.currentDir |
||||||
|
}, |
||||||
|
}, |
||||||
|
actions: { |
||||||
|
setFileInfo(file: string): void { |
||||||
|
this.file = file |
||||||
|
}, |
||||||
|
setCurrentDir(currentDir: string): void { |
||||||
|
this.currentDir = currentDir |
||||||
|
}, |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,23 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
interface FileState { |
||||||
|
file: string |
||||||
|
currentDir: string |
||||||
|
} |
||||||
|
|
||||||
|
export { FileState } |
@ -0,0 +1,48 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Intelligent display kb m |
||||||
|
*/ |
||||||
|
export const bytesToSize = (bytes: number) => { |
||||||
|
if (bytes === 0) return '0 B' |
||||||
|
const k = 1024 // or 1024
|
||||||
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] |
||||||
|
const i = Math.floor(Math.log(bytes) / Math.log(k)) |
||||||
|
|
||||||
|
return parseInt((bytes / Math.pow(k, i)).toPrecision(3)) + ' ' + sizes[i] |
||||||
|
} |
||||||
|
|
||||||
|
export const fileTypeArr = [ |
||||||
|
'txt', |
||||||
|
'log', |
||||||
|
'sh', |
||||||
|
'bat', |
||||||
|
'conf', |
||||||
|
'cfg', |
||||||
|
'py', |
||||||
|
'java', |
||||||
|
'sql', |
||||||
|
'xml', |
||||||
|
'hql', |
||||||
|
'properties', |
||||||
|
'json', |
||||||
|
'yml', |
||||||
|
'yaml', |
||||||
|
'ini', |
||||||
|
'js', |
||||||
|
] |
@ -0,0 +1,131 @@ |
|||||||
|
/* |
||||||
|
* 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, ref, toRefs } from 'vue' |
||||||
|
import { useRouter } from 'vue-router' |
||||||
|
import { NForm, NFormItem, NInput, NSelect, NButton } from 'naive-ui' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
|
||||||
|
import Card from '@/components/card' |
||||||
|
import MonacoEditor from '@/components/monaco-editor' |
||||||
|
import { useCreate } from './use-create' |
||||||
|
import { useForm } from './use-form' |
||||||
|
import { fileTypeArr } from '@/utils/common' |
||||||
|
|
||||||
|
import styles from '../index.module.scss' |
||||||
|
|
||||||
|
import type { Router } from 'vue-router' |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'ResourceFileCreate', |
||||||
|
setup() { |
||||||
|
const router: Router = useRouter() |
||||||
|
|
||||||
|
const codeEditorRef = ref() |
||||||
|
const { state } = useForm() |
||||||
|
const { handleCreateFile } = useCreate(state) |
||||||
|
|
||||||
|
const fileSuffixOptions = fileTypeArr.map((suffix) => ({ |
||||||
|
key: suffix, |
||||||
|
label: suffix, |
||||||
|
value: suffix, |
||||||
|
})) |
||||||
|
|
||||||
|
const handleFile = () => { |
||||||
|
state.fileForm.content = codeEditorRef.value?.getValue() |
||||||
|
handleCreateFile() |
||||||
|
} |
||||||
|
|
||||||
|
const handleReturn = () => { |
||||||
|
const { id } = router.currentRoute.value.params |
||||||
|
const name = id ? 'resource-file-subdirectory' : 'file' |
||||||
|
router.push({ name, params: { id } }) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
codeEditorRef, |
||||||
|
fileSuffixOptions, |
||||||
|
handleFile, |
||||||
|
handleReturn, |
||||||
|
...toRefs(state), |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
return ( |
||||||
|
<Card title={t('resource.file.file_details')}> |
||||||
|
<NForm |
||||||
|
rules={this.rules} |
||||||
|
ref='fileFormRef' |
||||||
|
label-placement='left' |
||||||
|
label-width='160' |
||||||
|
class={styles['form-content']} |
||||||
|
> |
||||||
|
<NFormItem label={t('resource.file.file_name')} path='fileName'> |
||||||
|
<NInput |
||||||
|
v-model={[this.fileForm.fileName, 'value']} |
||||||
|
placeholder={t('resource.file.enter_name_tips')} |
||||||
|
style={{ width: '300px' }} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.file_format')} path='suffix'> |
||||||
|
<NSelect |
||||||
|
defaultValue={[this.fileForm.suffix]} |
||||||
|
v-model={[this.fileForm.suffix, 'value']} |
||||||
|
options={this.fileSuffixOptions} |
||||||
|
style={{ width: '100px' }} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.description')} path='description'> |
||||||
|
<NInput |
||||||
|
type='textarea' |
||||||
|
v-model={[this.fileForm.description, 'value']} |
||||||
|
placeholder={t('resource.file.enter_description_tips')} |
||||||
|
style={{ width: '430px' }} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.file_content')} path='content'> |
||||||
|
<div |
||||||
|
class={styles.cont} |
||||||
|
style={{ |
||||||
|
width: '90%', |
||||||
|
}} |
||||||
|
> |
||||||
|
<MonacoEditor ref='codeEditorRef' /> |
||||||
|
</div> |
||||||
|
</NFormItem> |
||||||
|
<div class={styles['file-edit-content']}> |
||||||
|
<div class={styles.submit}> |
||||||
|
<NButton type='info' size='small' round onClick={this.handleFile}> |
||||||
|
{t('resource.file.save')} |
||||||
|
</NButton> |
||||||
|
<NButton |
||||||
|
type='info' |
||||||
|
size='small' |
||||||
|
text |
||||||
|
style={{ marginLeft: '15px' }} |
||||||
|
onClick={this.handleReturn} |
||||||
|
> |
||||||
|
{t('resource.file.return')} |
||||||
|
</NButton> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</NForm> |
||||||
|
</Card> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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 { useI18n } from 'vue-i18n' |
||||||
|
import { useRouter } from 'vue-router' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
import { useFileStore } from '@/store/file/file' |
||||||
|
import { onlineCreateResource } from '@/service/modules/resources' |
||||||
|
|
||||||
|
export function useCreate(state: any) { |
||||||
|
const { t } = useI18n() |
||||||
|
const router: Router = useRouter() |
||||||
|
const fileStore = useFileStore() |
||||||
|
|
||||||
|
const handleCreateFile = () => { |
||||||
|
const pid = router.currentRoute.value.params.id || -1 |
||||||
|
const currentDir = fileStore.getCurrentDir || '/' |
||||||
|
state.fileFormRef.validate(async (valid: any) => { |
||||||
|
if (!valid) { |
||||||
|
try { |
||||||
|
await onlineCreateResource({ |
||||||
|
...state.fileForm, |
||||||
|
...{ pid, currentDir }, |
||||||
|
}) |
||||||
|
|
||||||
|
window.$message.success(t('resource.file.success')) |
||||||
|
const name = pid ? 'resource-file-subdirectory' : 'file' |
||||||
|
router.push({ name, params: { id: pid } }) |
||||||
|
} catch (error: any) { |
||||||
|
window.$message.error(error.message) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
handleCreateFile, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,77 @@ |
|||||||
|
/* |
||||||
|
* 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 { useI18n } from 'vue-i18n' |
||||||
|
import { reactive, ref, unref } from 'vue' |
||||||
|
import type { FormRules } from 'naive-ui' |
||||||
|
|
||||||
|
const defaultValue = () => ({ |
||||||
|
pid: -1, |
||||||
|
type: 'FILE', |
||||||
|
suffix: 'sh', |
||||||
|
fileName: '', |
||||||
|
description: '', |
||||||
|
content: '', |
||||||
|
currentDir: '/', |
||||||
|
}) |
||||||
|
|
||||||
|
export function useForm() { |
||||||
|
const { t } = useI18n() |
||||||
|
|
||||||
|
const resetForm = () => { |
||||||
|
state.fileForm = Object.assign(unref(state.fileForm), defaultValue()) |
||||||
|
} |
||||||
|
|
||||||
|
const state = reactive({ |
||||||
|
fileFormRef: ref(), |
||||||
|
fileForm: defaultValue(), |
||||||
|
rules: { |
||||||
|
fileName: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.fileForm.fileName === '') { |
||||||
|
return new Error(t('resource.file.enter_name_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
suffix: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.fileForm.suffix === '') { |
||||||
|
return new Error(t('resource.file.enter_suffix_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
content: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.fileForm.content === '') { |
||||||
|
return new Error(t('resource.file.enter_content_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
} as FormRules, |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
state, |
||||||
|
resetForm, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,118 @@ |
|||||||
|
/* |
||||||
|
* 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 { useRouter } from 'vue-router' |
||||||
|
import { defineComponent, onMounted, ref, toRefs } from 'vue' |
||||||
|
import { NButton, NForm, NFormItem, NSpace } from 'naive-ui' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import Card from '@/components/card' |
||||||
|
import MonacoEditor from '@/components/monaco-editor' |
||||||
|
import { useForm } from './use-form' |
||||||
|
import { useEdit } from './use-edit' |
||||||
|
|
||||||
|
import styles from '../index.module.scss' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'ResourceFileEdit', |
||||||
|
setup() { |
||||||
|
const router: Router = useRouter() |
||||||
|
|
||||||
|
const resourceViewRef = ref() |
||||||
|
const codeEditorRef = ref() |
||||||
|
const routeNameRef = ref(router.currentRoute.value.name) |
||||||
|
const idRef = ref(Number(router.currentRoute.value.params.id)) |
||||||
|
|
||||||
|
const { state } = useForm() |
||||||
|
const { getResourceView, handleUpdateContent } = useEdit(state) |
||||||
|
|
||||||
|
const handleFileContent = () => { |
||||||
|
state.fileForm.content = codeEditorRef.value?.getValue() |
||||||
|
handleUpdateContent(idRef.value) |
||||||
|
} |
||||||
|
|
||||||
|
const handleReturn = () => { |
||||||
|
router.go(-1) |
||||||
|
} |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
resourceViewRef.value = getResourceView(idRef.value) |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
idRef, |
||||||
|
routeNameRef, |
||||||
|
codeEditorRef, |
||||||
|
resourceViewRef, |
||||||
|
handleReturn, |
||||||
|
handleFileContent, |
||||||
|
...toRefs(state), |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
return ( |
||||||
|
<Card title={t('resource.file.file_details')}> |
||||||
|
<div class={styles['file-edit-content']}> |
||||||
|
<h2> |
||||||
|
<span>{this.resourceViewRef?.value.alias}</span> |
||||||
|
</h2> |
||||||
|
<NForm |
||||||
|
rules={this.rules} |
||||||
|
ref='fileFormRef' |
||||||
|
class={styles['form-content']} |
||||||
|
> |
||||||
|
<NFormItem path='content'> |
||||||
|
<div |
||||||
|
class={styles.cont} |
||||||
|
style={{ |
||||||
|
width: '90%', |
||||||
|
}} |
||||||
|
> |
||||||
|
<MonacoEditor |
||||||
|
ref='codeEditorRef' |
||||||
|
modelValue={this.resourceViewRef?.value.content} |
||||||
|
/> |
||||||
|
</div> |
||||||
|
</NFormItem> |
||||||
|
{this.routeNameRef === 'resource-file-edit' && ( |
||||||
|
<NSpace> |
||||||
|
<NButton |
||||||
|
type='info' |
||||||
|
size='small' |
||||||
|
text |
||||||
|
style={{ marginRight: '15px' }} |
||||||
|
onClick={this.handleReturn} |
||||||
|
> |
||||||
|
{t('resource.file.return')} |
||||||
|
</NButton> |
||||||
|
<NButton |
||||||
|
type='info' |
||||||
|
size='small' |
||||||
|
round |
||||||
|
onClick={() => this.handleFileContent()} |
||||||
|
> |
||||||
|
{t('resource.file.save')} |
||||||
|
</NButton> |
||||||
|
</NSpace> |
||||||
|
)} |
||||||
|
</NForm> |
||||||
|
</div> |
||||||
|
</Card> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,64 @@ |
|||||||
|
/* |
||||||
|
* 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 { useI18n } from 'vue-i18n' |
||||||
|
import { useRouter } from 'vue-router' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
import { useAsyncState } from '@vueuse/core' |
||||||
|
import { |
||||||
|
viewResource, |
||||||
|
updateResourceContent, |
||||||
|
} from '@/service/modules/resources' |
||||||
|
|
||||||
|
export function useEdit(state: any) { |
||||||
|
const { t } = useI18n() |
||||||
|
const router: Router = useRouter() |
||||||
|
|
||||||
|
const getResourceView = (id: number) => { |
||||||
|
const params = { |
||||||
|
skipLineNum: 0, |
||||||
|
limit: 3000, |
||||||
|
} |
||||||
|
const { state } = useAsyncState(viewResource(params, id), {}) |
||||||
|
return state |
||||||
|
} |
||||||
|
|
||||||
|
const handleUpdateContent = (id: number) => { |
||||||
|
state.fileFormRef.validate(async (valid: any) => { |
||||||
|
if (!valid) { |
||||||
|
try { |
||||||
|
await updateResourceContent( |
||||||
|
{ |
||||||
|
...state.fileForm, |
||||||
|
}, |
||||||
|
id, |
||||||
|
) |
||||||
|
|
||||||
|
window.$message.success(t('resource.file.success')) |
||||||
|
router.go(-1) |
||||||
|
} catch (error: any) { |
||||||
|
window.$message.error(error.message) |
||||||
|
} |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
getResourceView, |
||||||
|
handleUpdateContent, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,53 @@ |
|||||||
|
/* |
||||||
|
* 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, unref } from 'vue' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import type { FormRules } from 'naive-ui' |
||||||
|
|
||||||
|
const defaultValue = () => ({ |
||||||
|
content: '', |
||||||
|
}) |
||||||
|
|
||||||
|
export function useForm() { |
||||||
|
const { t } = useI18n() |
||||||
|
|
||||||
|
const resetForm = () => { |
||||||
|
state.fileForm = Object.assign(unref(state.fileForm), defaultValue()) |
||||||
|
} |
||||||
|
|
||||||
|
const state = reactive({ |
||||||
|
fileFormRef: ref(), |
||||||
|
fileForm: defaultValue(), |
||||||
|
rules: { |
||||||
|
content: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.fileForm.content === '') { |
||||||
|
return new Error(t('resource.file.enter_content_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
} as FormRules, |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
state, |
||||||
|
resetForm, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,86 @@ |
|||||||
|
/* |
||||||
|
* 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, toRefs, PropType } from 'vue' |
||||||
|
import { NForm, NFormItem, NInput } from 'naive-ui' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import Modal from '@/components/modal' |
||||||
|
import { useForm } from './use-form' |
||||||
|
import { useFolder } from './use-folder' |
||||||
|
|
||||||
|
const props = { |
||||||
|
show: { |
||||||
|
type: Boolean as PropType<boolean>, |
||||||
|
default: false, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'ResourceFileFolder', |
||||||
|
props, |
||||||
|
emits: ['updateList', 'update:show'], |
||||||
|
setup(props, ctx) { |
||||||
|
const { state, resetForm } = useForm() |
||||||
|
const { handleCreateFolder } = useFolder(state) |
||||||
|
|
||||||
|
const hideModal = () => { |
||||||
|
ctx.emit('update:show') |
||||||
|
} |
||||||
|
|
||||||
|
const handleFolder = () => { |
||||||
|
handleCreateFolder(ctx.emit, hideModal, resetForm) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
hideModal, |
||||||
|
handleFolder, |
||||||
|
...toRefs(state), |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
return ( |
||||||
|
<Modal |
||||||
|
show={this.$props.show} |
||||||
|
title={t('resource.file.create_folder')} |
||||||
|
onCancel={this.hideModal} |
||||||
|
onConfirm={this.handleFolder} |
||||||
|
> |
||||||
|
<NForm |
||||||
|
rules={this.rules} |
||||||
|
ref='folderFormRef' |
||||||
|
label-placement='left' |
||||||
|
label-width='160' |
||||||
|
> |
||||||
|
<NFormItem label={t('resource.file.folder_name')} path='name'> |
||||||
|
<NInput |
||||||
|
v-model={[this.folderForm.name, 'value']} |
||||||
|
placeholder={t('resource.file.enter_name_tips')} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.description')} path='description'> |
||||||
|
<NInput |
||||||
|
type='textarea' |
||||||
|
v-model={[this.folderForm.description, 'value']} |
||||||
|
placeholder={t('resource.file.enter_description_tips')} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
</NForm> |
||||||
|
</Modal> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,59 @@ |
|||||||
|
/* |
||||||
|
* 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 { useI18n } from 'vue-i18n' |
||||||
|
import { IEmit } from '../types' |
||||||
|
import { useRouter } from 'vue-router' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
import { useFileStore } from '@/store/file/file' |
||||||
|
import { createDirectory } from '@/service/modules/resources' |
||||||
|
|
||||||
|
export function useFolder(state: any) { |
||||||
|
const { t } = useI18n() |
||||||
|
const router: Router = useRouter() |
||||||
|
const fileStore = useFileStore() |
||||||
|
|
||||||
|
const handleCreateFolder = ( |
||||||
|
emit: IEmit, |
||||||
|
hideModal: () => void, |
||||||
|
resetForm: () => void, |
||||||
|
) => { |
||||||
|
const pid = router.currentRoute.value.params.id || -1 |
||||||
|
const currentDir = fileStore.getCurrentDir || '/' |
||||||
|
state.folderFormRef.validate(async (valid: any) => { |
||||||
|
if (!valid) { |
||||||
|
try { |
||||||
|
await createDirectory({ |
||||||
|
...state.folderForm, |
||||||
|
...{ pid, currentDir }, |
||||||
|
}) |
||||||
|
|
||||||
|
window.$message.success(t('resource.file.success')) |
||||||
|
emit('updateList') |
||||||
|
} catch (error: any) { |
||||||
|
window.$message.error(error.message) |
||||||
|
} |
||||||
|
hideModal() |
||||||
|
resetForm() |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
handleCreateFolder, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,57 @@ |
|||||||
|
/* |
||||||
|
* 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, unref } from 'vue' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import type { FormRules } from 'naive-ui' |
||||||
|
|
||||||
|
const defaultValue = () => ({ |
||||||
|
pid: -1, |
||||||
|
type: 'FILE', |
||||||
|
name: '', |
||||||
|
description: '', |
||||||
|
currentDir: '/', |
||||||
|
}) |
||||||
|
|
||||||
|
export function useForm() { |
||||||
|
const { t } = useI18n() |
||||||
|
|
||||||
|
const resetForm = () => { |
||||||
|
state.folderForm = Object.assign(unref(state.folderForm), defaultValue()) |
||||||
|
} |
||||||
|
|
||||||
|
const state = reactive({ |
||||||
|
folderFormRef: ref(), |
||||||
|
folderForm: defaultValue(), |
||||||
|
rules: { |
||||||
|
name: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.folderForm.name === '') { |
||||||
|
return new Error(t('resource.file.enter_name_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
} as FormRules, |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
state, |
||||||
|
resetForm, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
.file-edit-content { |
||||||
|
width: 100%; |
||||||
|
background: #fff; |
||||||
|
padding-bottom: 20px; |
||||||
|
>h2 { |
||||||
|
line-height: 60px; |
||||||
|
text-align: center; |
||||||
|
padding-right: 170px; |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.form-content { |
||||||
|
padding: 0 50px 0 50px; |
||||||
|
} |
||||||
|
|
||||||
|
.submit { |
||||||
|
text-align: left; |
||||||
|
padding-top: 12px; |
||||||
|
margin-left: 160px; |
||||||
|
} |
||||||
|
|
||||||
|
.pagination { |
||||||
|
display: flex; |
||||||
|
justify-content: center; |
||||||
|
align-items: center; |
||||||
|
margin-top: 20px; |
||||||
|
} |
||||||
|
|
||||||
|
.table-box { |
||||||
|
table { |
||||||
|
width: 100%; |
||||||
|
tr { |
||||||
|
height: 40px; |
||||||
|
font-size: 12px; |
||||||
|
th,td{ |
||||||
|
&:nth-child(1) { |
||||||
|
width: 50px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
} |
||||||
|
th { |
||||||
|
&:nth-child(1) { |
||||||
|
width: 60px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
>span { |
||||||
|
font-size: 12px; |
||||||
|
color: #555; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,228 @@ |
|||||||
|
/* |
||||||
|
* 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 { useRouter } from 'vue-router' |
||||||
|
import { |
||||||
|
defineComponent, |
||||||
|
onMounted, |
||||||
|
ref, |
||||||
|
reactive, |
||||||
|
Ref, |
||||||
|
watch, |
||||||
|
inject, |
||||||
|
} from 'vue' |
||||||
|
import { NDataTable, NButtonGroup, NButton, NPagination } from 'naive-ui' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import Card from '@/components/card' |
||||||
|
import Conditions from '@/components/conditions' |
||||||
|
import { useTable } from './table/use-table' |
||||||
|
import { useFileState } from './use-file' |
||||||
|
import ResourceFolderModal from './folder' |
||||||
|
import ResourceUploadModal from './upload' |
||||||
|
import ResourceRenameModal from './rename' |
||||||
|
import { IRenameFile } from './types' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
import styles from './index.module.scss' |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'File', |
||||||
|
inject: ['reload'], |
||||||
|
setup() { |
||||||
|
const router: Router = useRouter() |
||||||
|
const fileId = ref(Number(router.currentRoute.value.params.id) || -1) |
||||||
|
|
||||||
|
const reload = inject('reload') |
||||||
|
const resourceListRef = ref() |
||||||
|
const folderShowRef = ref(false) |
||||||
|
const uploadShowRef = ref(false) |
||||||
|
const renameShowRef = ref(false) |
||||||
|
const serachRef = ref() |
||||||
|
|
||||||
|
const renameInfo = reactive({ |
||||||
|
id: -1, |
||||||
|
name: '', |
||||||
|
description: '', |
||||||
|
}) |
||||||
|
|
||||||
|
const paginationReactive = reactive({ |
||||||
|
page: 1, |
||||||
|
pageSize: 10, |
||||||
|
itemCount: 0, |
||||||
|
pageSizes: [10, 30, 50], |
||||||
|
}) |
||||||
|
|
||||||
|
const handleUpdatePage = (page: number) => { |
||||||
|
paginationReactive.page = page |
||||||
|
resourceListRef.value = getResourceListState( |
||||||
|
fileId.value, |
||||||
|
serachRef.value, |
||||||
|
paginationReactive.page, |
||||||
|
paginationReactive.pageSize, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const handleUpdatePageSize = (pageSize: number) => { |
||||||
|
paginationReactive.page = 1 |
||||||
|
paginationReactive.pageSize = pageSize |
||||||
|
resourceListRef.value = getResourceListState( |
||||||
|
fileId.value, |
||||||
|
serachRef.value, |
||||||
|
paginationReactive.page, |
||||||
|
paginationReactive.pageSize, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
const handleShowModal = (showRef: Ref<Boolean>) => { |
||||||
|
showRef.value = true |
||||||
|
} |
||||||
|
|
||||||
|
const setPagination = (count: number) => { |
||||||
|
paginationReactive.itemCount = count |
||||||
|
} |
||||||
|
|
||||||
|
const { getResourceListState } = useFileState(setPagination) |
||||||
|
|
||||||
|
const handleConditions = (val: string) => { |
||||||
|
serachRef.value = val |
||||||
|
resourceListRef.value = getResourceListState(fileId.value, val) |
||||||
|
} |
||||||
|
|
||||||
|
const handleCreateFolder = () => { |
||||||
|
handleShowModal(folderShowRef) |
||||||
|
} |
||||||
|
|
||||||
|
const handleCreateFile = () => { |
||||||
|
const name = fileId.value |
||||||
|
? 'resource-subfile-create' |
||||||
|
: 'resource-file-create' |
||||||
|
router.push({ |
||||||
|
name, |
||||||
|
params: { id: fileId.value }, |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
const handleUploadFile = () => { |
||||||
|
handleShowModal(uploadShowRef) |
||||||
|
} |
||||||
|
|
||||||
|
const handleRenameFile: IRenameFile = (id, name, description) => { |
||||||
|
renameInfo.id = id |
||||||
|
renameInfo.name = name |
||||||
|
renameInfo.description = description |
||||||
|
handleShowModal(renameShowRef) |
||||||
|
} |
||||||
|
|
||||||
|
const updateList = () => { |
||||||
|
resourceListRef.value = getResourceListState( |
||||||
|
fileId.value, |
||||||
|
serachRef.value, |
||||||
|
) |
||||||
|
} |
||||||
|
|
||||||
|
onMounted(() => { |
||||||
|
resourceListRef.value = getResourceListState(fileId.value) |
||||||
|
}) |
||||||
|
|
||||||
|
watch( |
||||||
|
() => router.currentRoute.value.params.id, |
||||||
|
() => reload(), |
||||||
|
) |
||||||
|
|
||||||
|
return { |
||||||
|
fileId, |
||||||
|
folderShowRef, |
||||||
|
uploadShowRef, |
||||||
|
renameShowRef, |
||||||
|
handleShowModal, |
||||||
|
resourceListRef, |
||||||
|
updateList, |
||||||
|
handleConditions, |
||||||
|
handleCreateFolder, |
||||||
|
handleCreateFile, |
||||||
|
handleUploadFile, |
||||||
|
handleRenameFile, |
||||||
|
handleUpdatePage, |
||||||
|
handleUpdatePageSize, |
||||||
|
pagination: paginationReactive, |
||||||
|
renameInfo, |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
const { columnsRef } = useTable(this.handleRenameFile, this.updateList) |
||||||
|
const { |
||||||
|
handleConditions, |
||||||
|
handleCreateFolder, |
||||||
|
handleCreateFile, |
||||||
|
handleUploadFile, |
||||||
|
} = this |
||||||
|
return ( |
||||||
|
<div> |
||||||
|
<Conditions onConditions={handleConditions}> |
||||||
|
<NButtonGroup> |
||||||
|
<NButton onClick={handleCreateFolder}> |
||||||
|
{t('resource.file.create_folder')} |
||||||
|
</NButton> |
||||||
|
<NButton onClick={handleCreateFile}> |
||||||
|
{t('resource.file.create_file')} |
||||||
|
</NButton> |
||||||
|
<NButton onClick={handleUploadFile}> |
||||||
|
{t('resource.file.upload_files')} |
||||||
|
</NButton> |
||||||
|
</NButtonGroup> |
||||||
|
</Conditions> |
||||||
|
<Card title={t('resource.file.file_manage')}> |
||||||
|
<NDataTable |
||||||
|
remote |
||||||
|
columns={columnsRef} |
||||||
|
data={this.resourceListRef?.value.table} |
||||||
|
striped |
||||||
|
size={'small'} |
||||||
|
class={styles['table-box']} |
||||||
|
/> |
||||||
|
<div class={styles.pagination}> |
||||||
|
<NPagination |
||||||
|
v-model:page={this.pagination.page} |
||||||
|
v-model:pageSize={this.pagination.pageSize} |
||||||
|
pageSizes={this.pagination.pageSizes} |
||||||
|
item-count={this.pagination.itemCount} |
||||||
|
onUpdatePage={this.handleUpdatePage} |
||||||
|
onUpdatePageSize={this.handleUpdatePageSize} |
||||||
|
show-quick-jumper |
||||||
|
show-size-picker |
||||||
|
/> |
||||||
|
</div> |
||||||
|
<ResourceFolderModal |
||||||
|
v-model:show={this.folderShowRef} |
||||||
|
onUpdateList={this.updateList} |
||||||
|
/> |
||||||
|
<ResourceUploadModal |
||||||
|
v-model:show={this.uploadShowRef} |
||||||
|
onUpdateList={this.updateList} |
||||||
|
/> |
||||||
|
<ResourceRenameModal |
||||||
|
v-model:show={this.renameShowRef} |
||||||
|
id={this.renameInfo.id} |
||||||
|
name={this.renameInfo.name} |
||||||
|
description={this.renameInfo.description} |
||||||
|
onUpdateList={this.updateList} |
||||||
|
/> |
||||||
|
</Card> |
||||||
|
</div> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,102 @@ |
|||||||
|
/* |
||||||
|
* 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, toRefs, PropType, watch } from 'vue' |
||||||
|
import { NForm, NFormItem, NInput } from 'naive-ui' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import Modal from '@/components/modal' |
||||||
|
import { useForm } from './use-form' |
||||||
|
import { useRename } from './use-rename' |
||||||
|
|
||||||
|
const props = { |
||||||
|
show: { |
||||||
|
type: Boolean as PropType<boolean>, |
||||||
|
default: false, |
||||||
|
}, |
||||||
|
id: { |
||||||
|
type: Number as PropType<number>, |
||||||
|
default: -1, |
||||||
|
}, |
||||||
|
name: { |
||||||
|
type: String as PropType<string>, |
||||||
|
default: '', |
||||||
|
}, |
||||||
|
description: { |
||||||
|
type: String as PropType<string>, |
||||||
|
default: '', |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'ResourceFileRename', |
||||||
|
props, |
||||||
|
emits: ['updateList', 'update:show'], |
||||||
|
setup(props, ctx) { |
||||||
|
const { state, resetForm } = useForm(props.name, props.description) |
||||||
|
const { handleRenameFile } = useRename(state) |
||||||
|
|
||||||
|
const hideModal = () => { |
||||||
|
ctx.emit('update:show', false) |
||||||
|
} |
||||||
|
|
||||||
|
const handleFile = () => { |
||||||
|
handleRenameFile(ctx.emit, hideModal, resetForm) |
||||||
|
} |
||||||
|
|
||||||
|
watch( |
||||||
|
() => props.name, |
||||||
|
() => { |
||||||
|
state.renameForm.id = props.id |
||||||
|
state.renameForm.name = props.name |
||||||
|
state.renameForm.description = props.description |
||||||
|
}, |
||||||
|
) |
||||||
|
|
||||||
|
return { hideModal, handleFile, ...toRefs(state) } |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
return ( |
||||||
|
<Modal |
||||||
|
show={this.$props.show} |
||||||
|
title={t('resource.file.rename')} |
||||||
|
onCancel={this.hideModal} |
||||||
|
onConfirm={this.handleFile} |
||||||
|
> |
||||||
|
<NForm |
||||||
|
rules={this.rules} |
||||||
|
ref='renameFormRef' |
||||||
|
label-placement='left' |
||||||
|
label-width='160' |
||||||
|
> |
||||||
|
<NFormItem label={t('resource.file.name')} path='name'> |
||||||
|
<NInput |
||||||
|
v-model={[this.renameForm.name, 'value']} |
||||||
|
placeholder={t('resource.file.enter_name_tips')} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.description')} path='description'> |
||||||
|
<NInput |
||||||
|
type='textarea' |
||||||
|
v-model={[this.renameForm.description, 'value']} |
||||||
|
placeholder={t('resource.file.enter_description_tips')} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
</NForm> |
||||||
|
</Modal> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,56 @@ |
|||||||
|
/* |
||||||
|
* 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, unref } from 'vue' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import type { FormRules } from 'naive-ui' |
||||||
|
|
||||||
|
const defaultValue = (name = '', description = '') => ({ |
||||||
|
id: -1, |
||||||
|
name, |
||||||
|
type: 'FILE', |
||||||
|
description, |
||||||
|
}) |
||||||
|
|
||||||
|
export function useForm(name: string, description: string) { |
||||||
|
const { t } = useI18n() |
||||||
|
|
||||||
|
const resetForm = () => { |
||||||
|
state.renameForm = Object.assign(unref(state.renameForm), defaultValue()) |
||||||
|
} |
||||||
|
|
||||||
|
const state = reactive({ |
||||||
|
renameFormRef: ref(), |
||||||
|
renameForm: defaultValue(name, description), |
||||||
|
rules: { |
||||||
|
name: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.renameForm.name === '') { |
||||||
|
return new Error(t('resource.file.enter_name_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
} as FormRules, |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
state, |
||||||
|
resetForm, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
/* |
||||||
|
* 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 { useI18n } from 'vue-i18n' |
||||||
|
import { IEmit } from '../types' |
||||||
|
import { updateResource } from '@/service/modules/resources' |
||||||
|
|
||||||
|
export function useRename(state: any) { |
||||||
|
const { t } = useI18n() |
||||||
|
|
||||||
|
const handleRenameFile = ( |
||||||
|
emit: IEmit, |
||||||
|
hideModal: () => void, |
||||||
|
resetForm: () => void, |
||||||
|
) => { |
||||||
|
state.renameFormRef.validate(async (valid: any) => { |
||||||
|
if (!valid) { |
||||||
|
try { |
||||||
|
await updateResource( |
||||||
|
{ |
||||||
|
...state.renameForm, |
||||||
|
}, |
||||||
|
state.renameForm.id, |
||||||
|
) |
||||||
|
window.$message.success(t('resource.file.success')) |
||||||
|
emit('updateList') |
||||||
|
} catch (error: any) { |
||||||
|
window.$message.error(error.message) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
hideModal() |
||||||
|
resetForm() |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
handleRenameFile, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
|
||||||
|
.links { |
||||||
|
color: #2080f0; |
||||||
|
text-decoration: none; |
||||||
|
&:hover { |
||||||
|
text-decoration: underline; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,190 @@ |
|||||||
|
/* |
||||||
|
* 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 { useRouter } from 'vue-router' |
||||||
|
import { defineComponent, PropType } from 'vue' |
||||||
|
import { NSpace, NTooltip, NButton, NIcon, NPopconfirm } from 'naive-ui' |
||||||
|
import { |
||||||
|
DeleteOutlined, |
||||||
|
DownloadOutlined, |
||||||
|
FormOutlined, |
||||||
|
EditOutlined, |
||||||
|
InfoCircleFilled, |
||||||
|
} from '@vicons/antd' |
||||||
|
import _ from 'lodash' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import { ResourceFileTableData } from '../types' |
||||||
|
import { fileTypeArr } from '@/utils/common' |
||||||
|
import { downloadResource, deleteResource } from '@/service/modules/resources' |
||||||
|
import { IRenameFile, IRtDisb } from '../types' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
|
||||||
|
const props = { |
||||||
|
show: { |
||||||
|
type: Boolean as PropType<boolean>, |
||||||
|
default: false, |
||||||
|
}, |
||||||
|
row: { |
||||||
|
type: Object as PropType<ResourceFileTableData>, |
||||||
|
default: { |
||||||
|
id: -1, |
||||||
|
name: '', |
||||||
|
description: '', |
||||||
|
}, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'TableAction', |
||||||
|
props, |
||||||
|
emits: ['updateList', 'renameResource'], |
||||||
|
setup(props, { emit }) { |
||||||
|
const { t } = useI18n() |
||||||
|
const router: Router = useRouter() |
||||||
|
|
||||||
|
const rtDisb: IRtDisb = (name, size) => { |
||||||
|
const i = name.lastIndexOf('.') |
||||||
|
const a = name.substring(i, name.length) |
||||||
|
const flag = _.includes(fileTypeArr, _.trimStart(a, '.')) |
||||||
|
return !(flag && size < 1000000) |
||||||
|
} |
||||||
|
|
||||||
|
const handleEditFile = (item: { id: number }) => { |
||||||
|
router.push({ name: 'resource-file-edit', params: { id: item.id } }) |
||||||
|
} |
||||||
|
|
||||||
|
const handleDeleteFile = (id: number) => { |
||||||
|
deleteResource(id).then(() => emit('updateList')) |
||||||
|
} |
||||||
|
|
||||||
|
const handleRenameFile: IRenameFile = (id, name, description) => { |
||||||
|
emit('renameResource', id, name, description) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
t, |
||||||
|
rtDisb, |
||||||
|
handleEditFile, |
||||||
|
handleDeleteFile, |
||||||
|
handleRenameFile, |
||||||
|
...props, |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
return ( |
||||||
|
<NSpace> |
||||||
|
<NTooltip trigger={'hover'}> |
||||||
|
{{ |
||||||
|
default: () => t('resource.file.edit'), |
||||||
|
trigger: () => ( |
||||||
|
<NButton |
||||||
|
size='tiny' |
||||||
|
type='info' |
||||||
|
disabled={this.rtDisb(this.row.name, this.row.size)} |
||||||
|
tag='div' |
||||||
|
onClick={() => { |
||||||
|
this.handleEditFile(this.row) |
||||||
|
}} |
||||||
|
style={{ marginRight: '-5px' }} |
||||||
|
circle |
||||||
|
> |
||||||
|
<NIcon> |
||||||
|
<FormOutlined /> |
||||||
|
</NIcon> |
||||||
|
</NButton> |
||||||
|
), |
||||||
|
}} |
||||||
|
</NTooltip> |
||||||
|
<NTooltip trigger={'hover'}> |
||||||
|
{{ |
||||||
|
default: () => t('resource.file.rename'), |
||||||
|
trigger: () => ( |
||||||
|
<NButton |
||||||
|
size='tiny' |
||||||
|
type='info' |
||||||
|
onClick={() => |
||||||
|
this.handleRenameFile( |
||||||
|
this.row.id, |
||||||
|
this.row.name, |
||||||
|
this.row.description, |
||||||
|
) |
||||||
|
} |
||||||
|
style={{ marginRight: '-5px' }} |
||||||
|
circle |
||||||
|
> |
||||||
|
<NIcon> |
||||||
|
<EditOutlined /> |
||||||
|
</NIcon> |
||||||
|
</NButton> |
||||||
|
), |
||||||
|
}} |
||||||
|
</NTooltip> |
||||||
|
<NTooltip trigger={'hover'}> |
||||||
|
{{ |
||||||
|
default: () => t('resource.file.download'), |
||||||
|
trigger: () => ( |
||||||
|
<NButton |
||||||
|
size='tiny' |
||||||
|
type='info' |
||||||
|
disabled={this.row?.directory ? true : false} |
||||||
|
tag='div' |
||||||
|
circle |
||||||
|
style={{ marginRight: '-5px' }} |
||||||
|
onClick={() => downloadResource(this.row.id)} |
||||||
|
> |
||||||
|
<NIcon> |
||||||
|
<DownloadOutlined /> |
||||||
|
</NIcon> |
||||||
|
</NButton> |
||||||
|
), |
||||||
|
}} |
||||||
|
</NTooltip> |
||||||
|
<NTooltip trigger={'hover'}> |
||||||
|
{{ |
||||||
|
default: () => t('resource.file.delete'), |
||||||
|
trigger: () => ( |
||||||
|
<NButton size='tiny' type='error' circle> |
||||||
|
<NPopconfirm |
||||||
|
positive-text={t('resource.file.confirm')} |
||||||
|
negative-text={t('resource.file.cancel')} |
||||||
|
onPositiveClick={() => { |
||||||
|
this.handleDeleteFile(this.row.id) |
||||||
|
}} |
||||||
|
> |
||||||
|
{{ |
||||||
|
default: () => t('resource.file.delete_confirm'), |
||||||
|
icon: () => ( |
||||||
|
<NIcon> |
||||||
|
<InfoCircleFilled /> |
||||||
|
</NIcon> |
||||||
|
), |
||||||
|
trigger: () => ( |
||||||
|
<NIcon> |
||||||
|
<DeleteOutlined /> |
||||||
|
</NIcon> |
||||||
|
), |
||||||
|
}} |
||||||
|
</NPopconfirm> |
||||||
|
</NButton> |
||||||
|
), |
||||||
|
}} |
||||||
|
</NTooltip> |
||||||
|
</NSpace> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,104 @@ |
|||||||
|
/* |
||||||
|
* 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 { useRouter } from 'vue-router' |
||||||
|
import { bytesToSize } from '@/utils/common' |
||||||
|
import { useFileStore } from '@/store/file/file' |
||||||
|
import TableAction from './table-action' |
||||||
|
import { IRenameFile } from '../types' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
import type { TableColumns } from 'naive-ui/es/data-table/src/interface' |
||||||
|
import styles from './index.module.scss' |
||||||
|
|
||||||
|
const goSubFolder = (router: Router, item: any) => { |
||||||
|
const fileStore = useFileStore() |
||||||
|
fileStore.setFileInfo(`${item.alias}|${item.size}`) |
||||||
|
|
||||||
|
if (item.directory) { |
||||||
|
fileStore.setCurrentDir(`${item.fullName}`) |
||||||
|
router.push({ name: 'resource-file-subdirectory', params: { id: item.id } }) |
||||||
|
} else { |
||||||
|
router.push({ name: 'resource-file-list', params: { id: item.id } }) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
export function useTable(renameResource: IRenameFile, updateList: () => void) { |
||||||
|
const { t } = useI18n() |
||||||
|
const router: Router = useRouter() |
||||||
|
|
||||||
|
const columnsRef: TableColumns<any> = [ |
||||||
|
{ |
||||||
|
title: t('resource.file.id'), |
||||||
|
key: 'id', |
||||||
|
width: 50, |
||||||
|
render: (_row, index) => index + 1, |
||||||
|
}, |
||||||
|
{ |
||||||
|
title: t('resource.file.name'), |
||||||
|
key: 'name', |
||||||
|
width: 120, |
||||||
|
render: (row) => |
||||||
|
h( |
||||||
|
'a', |
||||||
|
{ |
||||||
|
href: 'javascript:', |
||||||
|
class: styles.links, |
||||||
|
onClick: () => goSubFolder(router, row), |
||||||
|
}, |
||||||
|
{ |
||||||
|
default: () => { |
||||||
|
return row.name |
||||||
|
}, |
||||||
|
}, |
||||||
|
), |
||||||
|
}, |
||||||
|
{ title: t('resource.file.user_name'), width: 100, key: 'user_name' }, |
||||||
|
{ |
||||||
|
title: t('resource.file.whether_directory'), |
||||||
|
key: 'whether_directory', |
||||||
|
width: 100, |
||||||
|
render: (row) => |
||||||
|
row.directory ? t('resource.file.yes') : t('resource.file.no'), |
||||||
|
}, |
||||||
|
{ title: t('resource.file.file_name'), key: 'file_name' }, |
||||||
|
{ title: t('resource.file.description'), width: 150, key: 'description' }, |
||||||
|
{ |
||||||
|
title: t('resource.file.size'), |
||||||
|
key: 'size', |
||||||
|
render: (row) => bytesToSize(row.size), |
||||||
|
}, |
||||||
|
{ title: t('resource.file.update_time'), width: 150, key: 'update_time' }, |
||||||
|
{ |
||||||
|
title: t('resource.file.operation'), |
||||||
|
key: 'operation', |
||||||
|
width: 150, |
||||||
|
render: (row) => |
||||||
|
h(TableAction, { |
||||||
|
row, |
||||||
|
onRenameResource: (id, name, description) => |
||||||
|
renameResource(id, name, description), |
||||||
|
onUpdateList: () => updateList(), |
||||||
|
}), |
||||||
|
}, |
||||||
|
] |
||||||
|
|
||||||
|
return { |
||||||
|
columnsRef, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,66 @@ |
|||||||
|
/* |
||||||
|
* 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. |
||||||
|
*/ |
||||||
|
|
||||||
|
export interface ResourceFileTableData { |
||||||
|
id: number |
||||||
|
name: string |
||||||
|
user_name: string |
||||||
|
directory: string |
||||||
|
file_name: string |
||||||
|
description: string |
||||||
|
size: number |
||||||
|
update_time: string |
||||||
|
} |
||||||
|
|
||||||
|
export interface IEmit { |
||||||
|
(event: any, ...args: any[]): void |
||||||
|
} |
||||||
|
|
||||||
|
export interface IRenameFile { |
||||||
|
(id: number, name: string, description: string): void |
||||||
|
} |
||||||
|
export interface IRtDisb { |
||||||
|
(name: string, size: number): boolean |
||||||
|
} |
||||||
|
|
||||||
|
export interface IResourceListState { |
||||||
|
(id?: number, searchVal?: string, pageNo?: number, pageSize?: number): any |
||||||
|
} |
||||||
|
|
||||||
|
export interface BasicTableProps { |
||||||
|
title?: string |
||||||
|
dataSource: Function |
||||||
|
columns: any[] |
||||||
|
pagination: object |
||||||
|
showPagination: boolean |
||||||
|
actionColumn: any[] |
||||||
|
canResize: boolean |
||||||
|
resizeHeightOffset: number |
||||||
|
} |
||||||
|
|
||||||
|
export interface PaginationProps { |
||||||
|
page?: number |
||||||
|
pageCount?: number |
||||||
|
pageSize?: number |
||||||
|
pageSizes?: number[] |
||||||
|
showSizePicker?: boolean |
||||||
|
showQuickJumper?: boolean |
||||||
|
} |
||||||
|
|
||||||
|
export interface ISetPagination { |
||||||
|
(itemCount: number): void |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
/* |
||||||
|
* 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, toRefs, PropType } from 'vue' |
||||||
|
import { NButton, NForm, NFormItem, NInput, NUpload } from 'naive-ui' |
||||||
|
|
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import Modal from '@/components/modal' |
||||||
|
import { useForm } from './use-form' |
||||||
|
import { useUpload } from './use-upload' |
||||||
|
|
||||||
|
const props = { |
||||||
|
show: { |
||||||
|
type: Boolean as PropType<boolean>, |
||||||
|
default: false, |
||||||
|
}, |
||||||
|
} |
||||||
|
|
||||||
|
export default defineComponent({ |
||||||
|
name: 'ResourceFileUpload', |
||||||
|
props, |
||||||
|
emits: ['updateList', 'update:show'], |
||||||
|
setup(props, ctx) { |
||||||
|
const { state, resetForm } = useForm() |
||||||
|
const { handleUploadFile } = useUpload(state) |
||||||
|
|
||||||
|
const hideModal = () => { |
||||||
|
ctx.emit('update:show') |
||||||
|
} |
||||||
|
|
||||||
|
const customRequest = ({ file }: any) => { |
||||||
|
state.uploadForm.name = file.name |
||||||
|
state.uploadForm.file = file.file |
||||||
|
} |
||||||
|
|
||||||
|
const handleFile = () => { |
||||||
|
handleUploadFile(ctx.emit, hideModal, resetForm) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
hideModal, |
||||||
|
customRequest, |
||||||
|
handleFile, |
||||||
|
...toRefs(state), |
||||||
|
} |
||||||
|
}, |
||||||
|
render() { |
||||||
|
const { t } = useI18n() |
||||||
|
return ( |
||||||
|
<Modal |
||||||
|
show={this.$props.show} |
||||||
|
title={t('resource.file.upload_files')} |
||||||
|
onCancel={this.hideModal} |
||||||
|
onConfirm={this.handleFile} |
||||||
|
> |
||||||
|
<NForm |
||||||
|
rules={this.rules} |
||||||
|
ref='uploadFormRef' |
||||||
|
label-placement='left' |
||||||
|
label-width='160' |
||||||
|
> |
||||||
|
<NFormItem label={t('resource.file.file_name')} path='name'> |
||||||
|
<NInput |
||||||
|
v-model={[this.uploadForm.name, 'value']} |
||||||
|
placeholder={t('resource.file.enter_name_tips')} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.description')} path='description'> |
||||||
|
<NInput |
||||||
|
type='textarea' |
||||||
|
v-model={[this.uploadForm.description, 'value']} |
||||||
|
placeholder={t('resource.file.enter_description_tips')} |
||||||
|
/> |
||||||
|
</NFormItem> |
||||||
|
<NFormItem label={t('resource.file.upload_files')} path='file'> |
||||||
|
<NUpload |
||||||
|
v-model={[this.uploadForm.file, 'value']} |
||||||
|
customRequest={this.customRequest} |
||||||
|
> |
||||||
|
<NButton>{t('resource.file.upload_files')}</NButton> |
||||||
|
</NUpload> |
||||||
|
</NFormItem> |
||||||
|
</NForm> |
||||||
|
</Modal> |
||||||
|
) |
||||||
|
}, |
||||||
|
}) |
@ -0,0 +1,66 @@ |
|||||||
|
/* |
||||||
|
* 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, unref } from 'vue' |
||||||
|
import { useI18n } from 'vue-i18n' |
||||||
|
import type { FormRules } from 'naive-ui' |
||||||
|
|
||||||
|
const defaultValue = () => ({ |
||||||
|
name: '', |
||||||
|
file: '', |
||||||
|
description: '', |
||||||
|
pid: -1, |
||||||
|
currentDir: '/', |
||||||
|
}) |
||||||
|
|
||||||
|
export function useForm() { |
||||||
|
const { t } = useI18n() |
||||||
|
|
||||||
|
const resetForm = () => { |
||||||
|
state.uploadForm = Object.assign(unref(state.uploadForm), defaultValue()) |
||||||
|
} |
||||||
|
|
||||||
|
const state = reactive({ |
||||||
|
uploadFormRef: ref(), |
||||||
|
uploadForm: defaultValue(), |
||||||
|
rules: { |
||||||
|
name: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.uploadForm.name === '') { |
||||||
|
return new Error(t('resource.file.enter_name_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
file: { |
||||||
|
required: true, |
||||||
|
trigger: ['input', 'blur'], |
||||||
|
validator() { |
||||||
|
if (state.uploadForm.file === '') { |
||||||
|
return new Error(t('resource.file.enter_content_tips')) |
||||||
|
} |
||||||
|
}, |
||||||
|
}, |
||||||
|
} as FormRules, |
||||||
|
}) |
||||||
|
|
||||||
|
return { |
||||||
|
state, |
||||||
|
resetForm, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,64 @@ |
|||||||
|
/* |
||||||
|
* 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 { useI18n } from 'vue-i18n' |
||||||
|
import { IEmit } from '../types' |
||||||
|
import { useRouter } from 'vue-router' |
||||||
|
import type { Router } from 'vue-router' |
||||||
|
import { useFileStore } from '@/store/file/file' |
||||||
|
import { createResource } from '@/service/modules/resources' |
||||||
|
|
||||||
|
export function useUpload(state: any) { |
||||||
|
const { t } = useI18n() |
||||||
|
const router: Router = useRouter() |
||||||
|
const fileStore = useFileStore() |
||||||
|
|
||||||
|
const handleUploadFile = ( |
||||||
|
emit: IEmit, |
||||||
|
hideModal: () => void, |
||||||
|
resetForm: () => void, |
||||||
|
) => { |
||||||
|
state.uploadFormRef.validate(async (valid: any) => { |
||||||
|
const pid = router.currentRoute.value.params.id || -1 |
||||||
|
const currentDir = fileStore.getCurrentDir || '/' |
||||||
|
if (!valid) { |
||||||
|
const formData = new FormData() |
||||||
|
formData.append('file', state.uploadForm.file) |
||||||
|
formData.append('type', 'FILE') |
||||||
|
formData.append('name', state.uploadForm.name) |
||||||
|
formData.append('pid', String(pid)) |
||||||
|
formData.append('currentDir', currentDir) |
||||||
|
formData.append('description', state.uploadForm.description) |
||||||
|
|
||||||
|
try { |
||||||
|
await createResource(formData as any) |
||||||
|
window.$message.success(t('resource.file.success')) |
||||||
|
emit('updateList') |
||||||
|
} catch (error: any) { |
||||||
|
window.$message.error(error.message) |
||||||
|
} |
||||||
|
|
||||||
|
hideModal() |
||||||
|
resetForm() |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
return { |
||||||
|
handleUploadFile, |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,78 @@ |
|||||||
|
/* |
||||||
|
* 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 { useAsyncState } from '@vueuse/core' |
||||||
|
import { |
||||||
|
queryResourceListPaging, |
||||||
|
viewResource, |
||||||
|
} from '@/service/modules/resources' |
||||||
|
import type { ResourceListRes } from '@/service/modules/resources/types' |
||||||
|
import { IResourceListState, ISetPagination } from './types' |
||||||
|
|
||||||
|
export function useFileState( |
||||||
|
setPagination: ISetPagination = {} as ISetPagination, |
||||||
|
) { |
||||||
|
const getResourceListState: IResourceListState = ( |
||||||
|
id = -1, |
||||||
|
searchVal = '', |
||||||
|
pageNo = 1, |
||||||
|
pageSize = 10, |
||||||
|
) => { |
||||||
|
const { state } = useAsyncState( |
||||||
|
queryResourceListPaging({ |
||||||
|
id, |
||||||
|
type: 'FILE', |
||||||
|
searchVal, |
||||||
|
pageNo, |
||||||
|
pageSize, |
||||||
|
}).then((res: ResourceListRes): any => { |
||||||
|
const { total } = res |
||||||
|
setPagination(total) |
||||||
|
const table = res.totalList.map((item) => { |
||||||
|
return { |
||||||
|
id: item.id, |
||||||
|
name: item.alias, |
||||||
|
alias: item.alias, |
||||||
|
fullName: item.fullName, |
||||||
|
type: item.type, |
||||||
|
directory: item.directory, |
||||||
|
file_name: item.fileName, |
||||||
|
description: item.description, |
||||||
|
size: item.size, |
||||||
|
update_time: item.updateTime, |
||||||
|
} |
||||||
|
}) |
||||||
|
|
||||||
|
return { total, table } |
||||||
|
}), |
||||||
|
{ total: 0, table: [] }, |
||||||
|
) |
||||||
|
|
||||||
|
return state |
||||||
|
} |
||||||
|
|
||||||
|
const getResourceView = (id: number) => { |
||||||
|
const params = { |
||||||
|
skipLineNum: 0, |
||||||
|
limit: 3000, |
||||||
|
} |
||||||
|
const { state } = useAsyncState(viewResource(params, id), {}) |
||||||
|
return state |
||||||
|
} |
||||||
|
|
||||||
|
return { getResourceListState, getResourceView } |
||||||
|
} |
Loading…
Reference in new issue