Skip to content

Commit

Permalink
add secret new
Browse files Browse the repository at this point in the history
Signed-off-by: seven <zilisheng1996@gmail.com>
  • Loading branch information
Blankll committed Jan 30, 2024
1 parent c9f335c commit b941127
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/lang/enUS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,11 @@ export const enUS = {
empty: 'No history yet',
emptyDesc: 'History of queries will appear here as you execute Scans and Queries',
},
secret: {
new: 'New Secret',
name: 'Key Name',
type: 'Key Type',
priKey: 'Private Key',
pubKey: 'Public Key',
},
};
7 changes: 7 additions & 0 deletions src/lang/zhCN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,11 @@ export const zhCN = {
empty: '无历史记录',
emptyDesc: '执行扫描和查询时,查询历史记录将显示在此处',
},
secret: {
new: '新建密钥',
name: '名称',
type: '类型',
priKey: '私钥',
pubKey: '公钥',
},
};
13 changes: 9 additions & 4 deletions src/layout/components/the-aside.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@
}"
@click="navClick(item)"
>
<n-icon size="26">
<component :is="item.icon" />
</n-icon>
<n-icon size="26"> <v-icon :name="item.icon" /> </n-icon>
</div>
</the-aside-icon>
</div>
Expand Down Expand Up @@ -63,6 +61,13 @@ const mainNavList = ref([
icon: 'co-folder',
isLink: false,
},
{
id: 'secret',
path: '/secret',
name: 'Secret',
icon: 'gi-house-keys',
isLink: false,
},
{
id: 'history',
path: '/history',
Expand Down Expand Up @@ -90,7 +95,7 @@ const samllNavList = ref([
{
path: '/setting',
id: 'setting',
icon: 'io-settings-outline',
icon: 'co-settings',
name: 'setting',
isLink: false,
},
Expand Down
10 changes: 6 additions & 4 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,33 +10,35 @@ import {
MdAdd,
RiMore2Fill,
IoCloseOutline,
CoCheckCircle,
RiFileSearchLine,
OiDatabase,
BiFolder2Open,
BiGithub,
IoSettingsOutline,
CoSettings,
FaRegularUserCircle,
CoHistory,
BiHddStackFill,
CoFolder,
BiCheckLg,
GiHouseKeys,
} from 'oh-vue-icons/icons';

const app = createApp(App);
addIcons(
MdAdd,
RiMore2Fill,
IoCloseOutline,
CoCheckCircle,
BiCheckLg,
RiFileSearchLine,
OiDatabase,
BiFolder2Open,
BiGithub,
IoSettingsOutline,
CoSettings,
FaRegularUserCircle,
CoHistory,
BiHddStackFill,
CoFolder,
GiHouseKeys,
);
app.component('VIcon', OhVueIcon);

Expand Down
8 changes: 8 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ const router = createRouter({
},
component: () => import('../views/connect/index.vue'),
},
{
name: 'Secret',
path: '/secret',
meta: {
keepAlive: false,
},
component: () => import('../views/secret/index.vue'),
},
{
name: 'History',
path: '/history',
Expand Down
1 change: 1 addition & 0 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './appStore';
export * from './userStore';
export * from './connectionStore';
export * from './sourceFileStore';
export * from './secretStore';
26 changes: 26 additions & 0 deletions src/store/secretStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { defineStore } from 'pinia';

export enum SecretType {
SSH_KEY = 'SSH_KEY',
PASSWORD = 'PASSWORD',
}
export type Secret = {
id?: number;
name: string;
type: SecretType;
priKey?: string;
pubKey?: string;
username?: string;
password?: string;
};
export const useSecretStore = defineStore('secretStore', {
state(): {
secrets: Secret[];
} {
return {
secrets: [],
};
},
getters: {},
actions: {},
});
202 changes: 202 additions & 0 deletions src/views/secret/components/new-key-dialog.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
<template>
<n-modal v-model:show="showModal">
<n-card
style="width: 600px"
role="dialog"
aria-modal="true"
:title="modalTitle"
:bordered="false"
class="add-connect-modal-card"
@mask-click="closeModal"
>
<template #header-extra>
<n-icon size="26" @click="closeModal">
<v-icon name="io-close-outline" />
</n-icon>
</template>
<div class="modal-content">
<n-form
ref="connectFormRef"
label-placement="left"
label-width="100"
:model="formData"
:rules="formRules"
>
<n-grid cols="8" item-responsive responsive="screen" x-gap="10" y-gap="10">
<n-grid-item span="8">
<n-form-item :label="$t('secret.name')" path="name">
<n-input v-model:value="formData.name" clearable :placeholder="$t('secret.name')" />
</n-form-item>
</n-grid-item>
<n-grid-item span="8">
<n-form-item :label="$t('secret.priKey')" path="priKey">
<n-input
v-model:value="formData.priKey"
clearable
:placeholder="$t('secret.priKey')"
/>
</n-form-item>
</n-grid-item>
<n-grid-item span="8">
<n-form-item :label="$t('secret.pubKey')" path="pubKey">
<n-input-number
v-model:value="formData.pubKey"
clearable
:show-button="false"
:placeholder="$t('secret.pubKey')"
/>
</n-form-item>
</n-grid-item>
</n-grid>
</n-form>
</div>
<template #footer>
<div class="card-footer">
<div class="left">
<n-button
type="info"
:loading="testLoading"
:disabled="!validationPassed"
@click="testConnect"
>
{{ $t('connection.test') }}
</n-button>
</div>
<div class="right">
<n-button @click="closeModal">{{ $t('dialogOps.cancel') }}</n-button>
<n-button
type="primary"
:loading="saveLoading"
:disabled="!validationPassed"
@click="saveConnect"
>
{{ $t('dialogOps.confirm') }}
</n-button>
</div>
</div>
</template>
</n-card>
</n-modal>
</template>

<script setup lang="ts">
import { CustomError } from '../../../common';
import { Connection, Secret, useConnectionStore } from '../../../store';
import { useLang } from '../../../lang';
import { FormValidationError } from 'naive-ui';
const { testConnection, saveConnection } = useConnectionStore();
const lang = useLang();
// DOM
const connectFormRef = ref();
const showModal = ref(false);
const modalTitle = ref(lang.t('connection.add'));
const testLoading = ref(false);
const saveLoading = ref(false);
type SecretInput = Omit<Secret, 'id' | 'type'>;
const defaultFormData = {
name: '',
priKey: '',
pubKey: '',
username: '',
password: '',
};
const formData = ref<SecretInput>(defaultFormData);
const formRules = reactive({
name: [
{
required: true,
renderMessage: () => lang.t('secret.formValidation.nameRequired'),
trigger: ['input', 'blur'],
},
],
host: [
{
required: true,
renderMessage: () => lang.t('connection.formValidation.hostRequired'),
trigger: ['input', 'blur'],
},
],
port: [
{
required: true,
renderMessage: () => lang.t('connection.formValidation.portRequired'),
trigger: ['input', 'blur'],
},
],
});
const message = useMessage();
const cleanUp = () => {
formData.value = defaultFormData;
modalTitle.value = lang.t('connection.add');
};
const showMedal = (con: Connection | null) => {
cleanUp();
showModal.value = true;
if (con) {
formData.value = con;
modalTitle.value = lang.t('connection.edit');
}
};
const closeModal = () => {
showModal.value = false;
cleanUp();
};
const validationPassed = watch(formData.value, async () => {
try {
return await connectFormRef.value?.validate((errors: Array<FormValidationError>) => !errors);
} catch (e) {
return false;
}
});
const testConnect = async (event: MouseEvent) => {
event.preventDefault();
testLoading.value = !testLoading.value;
try {
await testConnection({ ...formData.value });

Check failure on line 161 in src/views/secret/components/new-key-dialog.vue

View workflow job for this annotation

GitHub Actions / pre-release (macos-latest, 20.x)

Argument of type '{ username?: string | undefined; password?: string | undefined; name: string; priKey?: string | undefined; pubKey?: string | undefined; }' is not assignable to parameter of type 'Connection'.

Check failure on line 161 in src/views/secret/components/new-key-dialog.vue

View workflow job for this annotation

GitHub Actions / pre-release (ubuntu-latest, 20.x)

Argument of type '{ username?: string | undefined; password?: string | undefined; name: string; priKey?: string | undefined; pubKey?: string | undefined; }' is not assignable to parameter of type 'Connection'.
message.success(lang.t('connection.testSuccess'));
} catch (e) {
const error = e as CustomError;
message.error(`status: ${error.status}, details: ${error.details}`, {
closable: true,
keepAliveOnHover: true,
duration: 10000,
});
} finally {
testLoading.value = !testLoading.value;
}
};
const saveConnect = async (event: MouseEvent) => {
event.preventDefault();
saveLoading.value = !saveLoading.value;
saveConnection(formData.value);

Check failure on line 178 in src/views/secret/components/new-key-dialog.vue

View workflow job for this annotation

GitHub Actions / pre-release (macos-latest, 20.x)

Argument of type '{ username?: string | undefined; password?: string | undefined; name: string; priKey?: string | undefined; pubKey?: string | undefined; }' is not assignable to parameter of type 'Connection'.

Check failure on line 178 in src/views/secret/components/new-key-dialog.vue

View workflow job for this annotation

GitHub Actions / pre-release (ubuntu-latest, 20.x)

Argument of type '{ username?: string | undefined; password?: string | undefined; name: string; priKey?: string | undefined; pubKey?: string | undefined; }' is not assignable to parameter of type 'Connection'.
saveLoading.value = !saveLoading.value;
showModal.value = false;
};
defineExpose({ showMedal });
</script>
<style lang="scss">
.add-connect-modal-card {
.n-card-header {
.n-card-header__extra {
cursor: pointer;
}
}
.n-card__footer {
.card-footer {
display: flex;
justify-content: space-between;
.n-button + .n-button {
margin-left: 10px;
}
}
}
}
</style>
40 changes: 40 additions & 0 deletions src/views/secret/components/tool-bar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<div class="tool-bar-container">
<n-button class="add-secret-btn" @click="addSecret">{{ $t('secret.new') }}</n-button>
</div>
</template>

<script setup lang="ts">
import { defineEmits } from 'vue';
const emit = defineEmits(['newSecretEmit']);
const addSecret = () => {
emit('newSecretEmit');
};
</script>

<style lang="scss" scoped>
.tool-bar-container {
height: 100%;
width: 100%;
display: flex;
align-items: center;
border: 1px solid var(--border-color);
.add-secret-btn {
height: 30px;
margin: 10px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
color: #fff;
background-color: var(--theme-color);
transition: 0.3s;
cursor: pointer;
&:hover {
background-color: var(--theme-color-hover);
}
}
}
</style>
Loading

0 comments on commit b941127

Please sign in to comment.