Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update sshkey page #2554

Merged
merged 24 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0c8d798
- Remove Active keys table
samaradel Apr 14, 2024
5153e27
- Collect SSH key functions in one file
samaradel Apr 16, 2024
3c4f6f5
remove type keyword
samaradel Apr 16, 2024
3245d9d
- Update functions with grid
samaradel Apr 17, 2024
4afe88e
Remove sshkey name from validator regex
samaradel Apr 17, 2024
cbd67ef
Add migrateSshKeys function in activate function
samaradel Apr 17, 2024
fbdba43
Revert "Add migrateSshKeys function in activate function"
samaradel Apr 17, 2024
4b56259
Revert "Remove sshkey name from validator regex"
samaradel Apr 17, 2024
f1963fa
Revert "- Update functions with grid"
samaradel Apr 17, 2024
a366dc9
Revert "remove type keyword"
samaradel Apr 17, 2024
382f06a
Revert "- Collect SSH key functions in one file"
samaradel Apr 17, 2024
14d3005
Fix listing imported keys when its imported without name
samaradel Apr 17, 2024
8957552
Apply loading while activating or deactivating ssh keys
samaradel Apr 17, 2024
9ce6514
Enhanced the 'SSH-Keys' page with the following:
Mahmoud-Emad Apr 18, 2024
a75228a
Fix: Fix bug in listing ssh-keys for a new user, fix issue in display…
Mahmoud-Emad Apr 18, 2024
88ab913
Fix: Fix bug in listing ssh-keys for a new user, fix issue in display…
Mahmoud-Emad Apr 18, 2024
6a18966
Apply comments:
Mahmoud-Emad Apr 18, 2024
33eb81e
Removed unused loggers.
Mahmoud-Emad Apr 18, 2024
c5fd3b5
Update the header font size.
Mahmoud-Emad Apr 18, 2024
709a1a8
Fix: Fixed the issue of exporting some keys by looping over the selec…
Mahmoud-Emad Apr 18, 2024
e3359fd
Enhancements:
Mahmoud-Emad Apr 21, 2024
b2acbb5
Fix: Handled Insufficient Balance Error
Mahmoud-Emad Apr 21, 2024
bd73ce3
Update: Update the status of the key if the balance is enough
Mahmoud-Emad Apr 21, 2024
d097eea
Update: Handle error message, handle error blocks.
Mahmoud-Emad Apr 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<v-card class="" variant="tonal">
<v-card class="my-6" variant="tonal">
<v-card-title>
<v-icon>mdi-key-chain</v-icon>
Manage SSH keys
Expand All @@ -17,7 +17,15 @@

<v-card-actions>
<VSpacer />
<v-btn color="primary" variant="flat" @click="openManageDialog = true" class="mr-2">Manage SSH keys</v-btn>
<v-btn
color="primary"
variant="flat"
@click="openManageDialog = true"
class="mr-2 my-1"
:disabled="sshKeys && sshKeys.length === 0"
>
Manage SSH keys
</v-btn>
</v-card-actions>
</v-card>

Expand Down
47 changes: 31 additions & 16 deletions packages/playground/src/components/ssh_keys/SshFormDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@
<template v-slot:default>
<v-card>
<v-toolbar color="primary" class="custom-toolbar">
<p v-if="$props.dialogType === SSHCreationMethod.Generate" class="mb-5">Add new SSH Key</p>
<p v-else-if="$props.dialogType === SSHCreationMethod.Import" class="mb-5">Import an exact SSH Key</p>
<p class="mb-5">
{{
$props.dialogType === SSHCreationMethod.Generate ? "Generate a new SSH Key" : "Import an exact SSH Key"
}}
</p>
</v-toolbar>

<v-card-text>
Expand All @@ -21,7 +24,7 @@
<v-text-field
hint="Leave this field empty to generate a name automatically, or enter a custom name to save it with your key."
:rules="[
keyName.length < 15 || 'Please enter a key name with fewer than 15 characters.',
keyName.length < 30 || 'Please enter a key name with fewer than 30 characters.',
!keyName.includes(' ') || 'Key names cannot include spaces. Please use a name without spaces.',
]"
class="mb-4"
Expand All @@ -32,7 +35,8 @@
</input-tooltip>

<v-alert width="95%" class="mb-4" type="info">
Updating or generating SSH key will cost you up to 0.01 TFT
{{ $props.dialogType === SSHCreationMethod.Generate ? "Generating" : "Importing" }}
a new SSH key will cost you up to 0.01 TFT
</v-alert>

<div v-if="$props.dialogType === SSHCreationMethod.Generate" class="create">
Expand Down Expand Up @@ -82,7 +86,7 @@
<v-btn
v-if="$props.dialogType === SSHCreationMethod.Import"
:loading="$props.savingKey"
:disabled="!sshKey || !isValidSSHKey(sshKey)"
:disabled="!sshKey || !sshKeysManagement.isValidSSHKey(sshKey) || keyName.length >= 30"
color="secondary"
variant="outlined"
text="Save"
Expand All @@ -100,11 +104,10 @@ import { computed, defineComponent, type PropType, ref, watch } from "vue";

import { type Profile, useProfileManager } from "@/stores/profile_manager";
import { SSHCreationMethod, type SSHKeyData } from "@/types";
import { formatSSHKeyTableCreatedAt } from "@/utils/date";
import { createCustomToast, ToastType } from "@/utils/custom_toast";
import { type Balance, getGrid, loadBalance } from "@/utils/grid";
import { isEnoughBalance } from "@/utils/helpers";
import { generateSSHKeyName } from "@/utils/strings";
import { isValidSSHKey } from "@/utils/validators";
import SSHKeysManagement from "@/utils/ssh";

export default defineComponent({
emits: ["close", "save", "generate"],
Expand Down Expand Up @@ -137,6 +140,8 @@ export default defineComponent({

setup(props, { emit }) {
const profileManager = useProfileManager();
const sshKeysManagement = new SSHKeysManagement();

const sshKey = ref<string>("");
const keyName = ref<string>(generateUniqueSSHKeyName());
const createdKey = ref<SSHKeyData | null>(null); // Initialize createdKey with null
Expand All @@ -150,17 +155,18 @@ export default defineComponent({
isOpen => {
if (isOpen) {
const now = new Date();
const lastID = props.allKeys.length ? props.allKeys[props.allKeys.length - 1].id : 1;
const keyId = props.allKeys.length ? props.allKeys[props.allKeys.length - 1].id + 1 : 1;

keyName.value = generateUniqueSSHKeyName();
sshKey.value = "";
createdKey.value = {
id: lastID + 1,
id: keyId,
publicKey: props.generatedSshKey as string,
createdAt: formatSSHKeyTableCreatedAt(now),
name: keyName.value.length === 0 ? generateUniqueSSHKeyName() : keyName.value,
createdAt: sshKeysManagement.formatDate(now),
name: keyName.value,
isActive: true,
};
} else {
keyName.value = generateUniqueSSHKeyName();
}
},
{ deep: true },
Expand All @@ -184,13 +190,22 @@ export default defineComponent({
if (createdKey.value) {
const isNewSSHKey = ref<boolean>(props.dialogType === SSHCreationMethod.Generate);
createdKey.value.publicKey = isNewSSHKey.value ? props.generatedSshKey || "" : sshKey.value;
const parts = createdKey.value.publicKey.split(" ");

if (parts.length === 3) {
if (parts[parts.length - 1].length < 30) {
keyName.value = parts[parts.length - 1];
}
}

createdKey.value.name = keyName.value;
emit("save", createdKey.value);
}
}

function generateUniqueSSHKeyName(depth = 0): string {
const keyName: string = generateSSHKeyName();
const keyName: string = sshKeysManagement.generateName();

if (!props.allKeys.length) {
return keyName;
}
Expand Down Expand Up @@ -242,7 +257,7 @@ export default defineComponent({
return [
(v: any) => !!v || "SSH key is required.",
(v: string) =>
isValidSSHKey(v) ||
sshKeysManagement.isValidSSHKey(v) ||
"The SSH key you provided is not valid. Please double-check that it is copied correctly and follows the correct format.",
];
}
Expand All @@ -253,12 +268,12 @@ export default defineComponent({
hasEnoughBalance,
sshKey,
SSHCreationMethod,
sshKeysManagement,

generateUniqueSSHKeyName,
createNewSSHKey,
sshRules,
generateSSHKey,
isValidSSHKey,
};
},
});
Expand Down
87 changes: 45 additions & 42 deletions packages/playground/src/components/ssh_keys/SshTable.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<template>
<v-card class="pt-6 pl-6 pr-6 mb-4">
<div class="head">
<h2 class="text-light">
<v-icon>{{ headerIcon }}</v-icon>
{{ headerTitle }}
</h2>
<h3 class="text-light">
<v-icon>mdi-key-chain</v-icon>
SSH Keys
</h3>
</div>

<div class="table mt-3">
Expand All @@ -24,7 +24,11 @@
loading-text="Loading..."
@click:row="(_, { item }) => $emit('view', item.raw)"
>
<template #loading> </template>
<template #loading>
<div class="w-100 text-center" v-if="loading && loadingMessage">
<small>{{ loadingMessage }}</small>
</div>
</template>
<template #[`item.createdAt`]="{ item }">
<v-tooltip location="bottom" :text="`The date when this SSH key was created.`">
<template #activator="{ props }">
Expand Down Expand Up @@ -64,36 +68,28 @@
<template #[`item.activation`]="{ item }">
<v-tooltip
location="bottom"
v-if="item.raw.isActive"
:text="`The '${item.raw.name}' key is currently activated and will be utilized in deployments.`"
:text="
item.raw.isActive
? `The '${item.raw.name}' key is currently activated and will be utilized in deployments.`
: `Click to activate the '${item.raw.name}' for use in deployments.`
"
>
<template #activator="{ props }">
<v-progress-circular
v-if="item.raw.activating"
:size="20"
:width="2"
color="info"
indeterminate
></v-progress-circular>
<VCheckboxBtn
v-else
class="d-inline"
:disabled="loading"
v-bind="props"
:loading="item.raw.activating"
color="secondary"
@click="activateKey(item.raw)"
:model-value="item.raw.isActive"
/>
</template>
</v-tooltip>

<v-tooltip
location="bottom"
v-else
:text="`Click to activate the '${item.raw.name}' for use in deployments.`"
>
<template #activator="{ props }">
<VCheckboxBtn
class="d-inline"
:disabled="loading"
v-bind="props"
:loading="item.raw.activating"
:color="theme.name.value === AppThemeSelection.light ? '' : 'grey-lighten-1'"
@click="activateKey(item.raw)"
@click.stop="toggleKeyActivation(item.raw)"
:model-value="item.raw.isActive"
:disabled="deleting"
/>
</template>
</v-tooltip>
Expand Down Expand Up @@ -153,11 +149,7 @@ export default defineComponent({
type: Array as PropType<SSHKeyData[]>,
required: true,
},
headerTitle: {
type: String,
required: true,
},
headerIcon: {
loadingMessage: {
type: String,
required: true,
},
Expand All @@ -171,7 +163,7 @@ export default defineComponent({
},
},

emits: ["inactive", "active", "delete", "view", "update:keys", "export"],
emits: ["delete", "view", "update:activation", "export"],

setup(props, { emit }) {
const selectedKeys = ref<number[]>([]); // IDs
Expand Down Expand Up @@ -214,20 +206,26 @@ export default defineComponent({
emit("delete", [key]);
};

const activateKey = (key: SSHKeyData) => {
if (key.isActive) {
emit("inactive", key);
} else {
emit("active", key);
}
const toggleKeyActivation = (key: SSHKeyData) => {
console.log(key.isActive);
Mahmoud-Emad marked this conversation as resolved.
Show resolved Hide resolved
emit("update:activation", key);
};

return { headers, selectedKeys, capitalize, theme, AppThemeSelection, deleteSelected, deleteKey, activateKey };
return {
headers,
selectedKeys,
theme,
AppThemeSelection,
capitalize,
deleteSelected,
deleteKey,
toggleKeyActivation,
};
},
});
</script>

<style scoped>
<style>
.head {
border-bottom: 1px solid #8d848d;
padding-bottom: 15px;
Expand All @@ -241,4 +239,9 @@ export default defineComponent({
.activation {
cursor: pointer;
}
.v-data-table-rows-loading td {
padding: 0 !important;
margin: 0 !important;
height: 25px !important;
}
</style>
4 changes: 0 additions & 4 deletions packages/playground/src/utils/date.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,3 @@ import moment from "moment";
export default function toHumanDate(timeInSeconds: number): string {
return moment(timeInSeconds * 1000).format("M/D/YY, h:m A");
}

export function formatSSHKeyTableCreatedAt(date: Date) {
return `${date.getDate()}-${date.getMonth() + 1}-${date.getFullYear()}`;
}
Loading
Loading