Skip to content

Commit

Permalink
Frontend: improvements to kraken ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Williangalvani committed Feb 13, 2025
1 parent a4b3196 commit e03c17b
Showing 1 changed file with 136 additions and 48 deletions.
184 changes: 136 additions & 48 deletions core/frontend/src/components/kraken/modals/ExtensionCreationModal.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<template>
<template>
<v-dialog
v-if="extension"
width="700"
Expand All @@ -8,11 +8,26 @@
@click:outside="closeDialog"
>
<v-card>
<v-card-title>
{{ is_editing ? 'Edit' : 'Create' }} Extension
<v-card-title class="d-flex align-center justify-space-between">
<span>{{ is_editing ? 'Edit' : 'Create' }} Extension</span>
<v-btn
icon
x-small
class="ml-2"
:color="copySuccess ? 'success' : undefined"
title="Copy configuration"
@click="copyConfig"
>
<v-icon small>
{{ copySuccess ? 'mdi-check' : 'mdi-content-copy' }}
</v-icon>
</v-btn>
</v-card-title>

<v-card-text class="d-flex flex-column">
<v-card-text
class="d-flex flex-column"
@paste="handlePaste"
>
<v-form
ref="form"
lazy-validation
Expand Down Expand Up @@ -45,24 +60,24 @@

<json-editor
v-model="new_permissions"
style="width:100%; height:100%"
@save="onEditingPermissionsSave"
style="width:100%; height:100%"
@save="onEditingPermissionsSave"
>
<template
v-if="is_reset_editing_permissions_visible"
#controls
>
<template
v-if="is_reset_editing_permissions_visible"
#controls
<v-btn
v-tooltip="'Reset to default permissions'"
class="editor-control"
icon
color="white"
@click="resetToDefaultPermissions"
>
<v-btn
v-tooltip="'Reset to default permissions'"
class="editor-control"
icon
color="white"
@click="resetToDefaultPermissions"
>
<v-icon>mdi-restore</v-icon>
</v-btn>
</template>
</json-editor>
<v-icon>mdi-restore</v-icon>
</v-btn>
</template>
</json-editor>

<v-btn
color="primary"
Expand All @@ -80,11 +95,16 @@
<script lang="ts">
import Vue, { PropType } from 'vue'
import JsonEditor from '@/components/common/JsonEditor.vue'
import { InstalledExtensionData } from '@/types/kraken'
import { VForm } from '@/types/vuetify'
import { copyToClipboard } from '@/utils/clipboard'
export default Vue.extend({
name: 'ExtensionCreationModal',
components: {
JsonEditor,
},
model: {
prop: 'extension',
event: 'change',
Expand All @@ -98,17 +118,22 @@ export default Vue.extend({
data() {
return {
new_extension: this.extension,
new_permissions: this.extension?.permissions ?? '{}',
new_extension: this.extension ?? {
identifier: '',
name: '',
docker: '',
tag: '',
permissions: '{}',
editing: false,
} as InstalledExtensionData & { editing: boolean },
new_permissions: JSON.parse(this.extension?.permissions ?? '{}'),
copySuccess: false,
}
},
computed: {
form(): VForm {
return this.$refs.form as VForm
},
formatted_permissions() {
return JSON.stringify(JSON.parse(this.new_extension?.permissions ?? '{}'), null, 2)
},
is_editing() {
return this.extension?.editing ?? false
},
Expand All @@ -120,8 +145,24 @@ export default Vue.extend({
new_extension() {
this.$emit('input', this.new_extension)
},
new_permissions(new_permissions: string) {
if (JSON.parse(new_permissions)) {
this.new_extension.permissions = new_permissions
}
},
extension() {
this.new_extension = this.extension
if (this.extension) {
this.new_extension = { ...this.extension }
} else {
this.new_extension = {
identifier: '',
name: '',
docker: '',
tag: '',
permissions: '{}',
editing: false,
} as InstalledExtensionData & { editing: boolean }
}
this.new_permissions = JSON.parse(this.extension?.permissions ?? '{}')
if (this.is_editing && this.new_extension?.permissions) {
this.new_extension.user_permissions = this.new_extension.permissions
Expand All @@ -134,11 +175,18 @@ export default Vue.extend({
methods: {
onEditingPermissionsSave(permissions: string) {
if (this.new_extension) {
this.new_extension.permissions = permissions
this.new_extension.permissions = JSON.stringify(permissions)
}
},
closeDialog() {
this.new_extension = null
this.new_extension = {
identifier: '',
name: '',
docker: '',
tag: '',
permissions: '{}',
editing: false,
} as InstalledExtensionData & { editing: boolean }
this.$emit('closed')
},
resetToDefaultPermissions() {
Expand Down Expand Up @@ -189,26 +237,6 @@ export default Vue.extend({
}
return true
},
validate_permissions(input: string): (true | string) {
try {
JSON.parse(input)
return true
} catch {
return 'This entry must be in valid JSON format.'
}
},
validate_user_permissions(input: string): (true | string) {
if (input === '') {
return true
}
try {
JSON.parse(input)
return true
} catch {
return 'This entry must be in valid JSON format.'
}
},
validate_tag(input: string) {
if (input.includes(' ')) {
return 'Tag name must not include spaces.'
Expand All @@ -235,6 +263,66 @@ export default Vue.extend({
this.$emit('change', state)
}
},
async copyConfig() {
if (!this.new_extension) {
return
}
const config = {
identifier: this.new_extension.identifier,
name: this.new_extension.name,
docker: this.new_extension.docker,
tag: this.new_extension.tag,
permissions: this.new_extension.permissions,
}
const jsonString = JSON.stringify(config, null, 2)
const success = await copyToClipboard(jsonString)
if (success) {
this.copySuccess = true
setTimeout(() => {
this.copySuccess = false
}, 2000) // Reset after 2 seconds
}
},
handlePaste(event: ClipboardEvent) {
try {
// Get the pasted text
const pastedText = event.clipboardData?.getData('text')
if (!pastedText) return
// Try to parse it as JSON
const config = JSON.parse(pastedText)
// Validate that it has the expected structure
if (config.identifier && config.name && config.docker && config.tag) {
// Prevent the default paste
event.preventDefault()
// Update the form data
if (!this.new_extension) {
this.new_extension = {} as InstalledExtensionData & { editing: boolean }
}
this.new_extension.identifier = config.identifier
this.new_extension.name = config.name
this.new_extension.docker = config.docker
this.new_extension.tag = config.tag
// Handle permissions if present
if (config.permissions) {
this.new_extension.permissions = typeof config.permissions === 'string'
? config.permissions
: JSON.stringify(config.permissions)
this.new_permissions = JSON.parse(this.new_extension.permissions)
}
}
} catch (error) {
// Not valid JSON or doesn't match our format - ignore
console.debug('Pasted content was not valid extension configuration')
}
},
},
})
</script>

0 comments on commit e03c17b

Please sign in to comment.