Skip to content

Commit

Permalink
Changes required to update InputDialog kept growing more and more due…
Browse files Browse the repository at this point in the history
… to its usage across the application. seperating this off to take a look at it and see what else can get done first.
  • Loading branch information
SeriousHorncat committed Nov 4, 2024
1 parent ffe8ad8 commit a68f40e
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 300 deletions.
267 changes: 226 additions & 41 deletions frontend/src/components/Dialogs/InputDialog.vue
Original file line number Diff line number Diff line change
@@ -1,68 +1,253 @@
<template>
<div v-if="dialog.state.active" class="modal-background">
<div :class="['modal-container', dialog.state.message ? 'limit-width' : '']">
<div v-if="state.active" class="modal-background">
<div :class="['modal-container', state.message ? 'limit-width' : '']">
<div class="tab-header">
<button
v-for="(tab, index) in dialog.state.tabs"
v-for="(tab, index) in state.tabs"
:key="`button-${tab.name}-${index}`"
:class="tab.name == dialog.state.activeTabName ? 'tab-button-active' : ''"
:class="tab.name == activeTabName ? 'tab-button-active' : ''"
class="tab-button"
@click="dialog.state.activeTabName = tab.name"
@click="toggleTab(tab.name)"
:data-test="`button-${tab.name}`"
>
<img
v-if="tab.icon == 'phenotips'"
src="@/assets/phenotips-favicon-96x96.png"
/>
<font-awesome-icon v-else
:icon="'file' == tab.icon ? ['far', 'file'] : tab.icon"
size="2xl">
<img v-if="tab.icon == 'phenotips'" src="@/assets/phenotips-favicon-96x96.png"/>
<font-awesome-icon v-else :icon="'file' == tab.icon ? ['far', 'file'] : tab.icon" size="2xl">
</font-awesome-icon>
</button>
</div>
<div v-if="dialog.state.message"
<div v-if="state.message"
class="warning-message"
v-html="dialog.state.message"
v-html="state.message"
data-test="warning-message">
</div>
<component v-bind:is="dialog.state.activeTabName"
:userInput = "dialog.activeTab().input"
v-bind="dialog.activeTab().props"
@update:userInput="dialog.updateActiveTabInput"
<component v-bind:is="activeTabName"
:userInput = "activeTabInput"
v-bind="activeTabProps"
@update:userInput="updateActiveTabInput"
:data-test = 'activeTabName'
/>
<div class="button-row">
<button class="secondary-button" @click="dialog.cancel()" data-test="cancel">
{{ dialog.state.cancelText }}
<button class="secondary-button" @click="cancel()" data-test="cancel">
{{ state.cancelText }}
</button>
<button class="secondary-button" v-if="dialog.state.deleteText!=''" @click="dialog.delete()" data-test="delete">
{{ dialog.state.deleteText }}
<button class="secondary-button" v-if="deleteEnabled" @click="remove()" data-test="remove">
{{ state.removeText }}
</button>
<button class="primary-button" @click="dialog.confirmation(dialog.activeTab().input)" data-test="confirm">
{{ dialog.state.confirmText }}
<button class="primary-button" @click="confirmation(activeTab.input)" data-test="confirm">
{{ state.confirmText }}
</button>
</div>
</div>
</div>
</template>

<script>
import InputDialogAttachUrl from '@/components/Dialogs/InputDialogAttachUrl.vue';
import InputDialogUploadFile from '@/components/Dialogs/InputDialogUploadFile.vue';
import dialog from '@/inputDialog.js';
export default {
name: 'input-dialog',
components: {
InputDialogAttachUrl,
InputDialogUploadFile,
},
data: function() {
return {
dialog,
};
},
<script setup>
import {computed, reactive} from 'vue';
const state = reactive({
tabs: [],
active: false,
activeTabName: '',
confirmText: 'Ok',
cancelText: 'Cancel',
removeText: '',
message: '',
});
const activeTab = computed(() => {
if ('' == state.activeTabName) {
return undefined;
}
console.log(`InputDialog computed ${state.activeTabName}`)

Check failure on line 63 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
console.log(state.tabs.find((tab) => tab.name === state.activeTabName))

Check failure on line 64 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
return state.tabs.find((tab) => tab.name === state.activeTabName);
})

Check failure on line 66 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
const activeTabName = computed(() => {
console.log(`InputDialog:ActiveTabName Computed = ${state.activeTabName}`)

Check failure on line 69 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
return state.activeTabName;
});
const activeTabInput = computed(() => {
return activeTab.input

Check failure on line 74 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Must use `.value` to read or write the value wrapped by `computed()`

Check failure on line 74 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
});
const activeTabProps = computed(() => {
return activeTab.props

Check failure on line 78 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Must use `.value` to read or write the value wrapped by `computed()`

Check failure on line 78 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
});
const deleteEnabled = computed(() => {
return state.removeText!=''

Check failure on line 82 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Expected indentation of 2 spaces but found 1

Check failure on line 82 in frontend/src/components/Dialogs/InputDialog.vue

View workflow job for this annotation

GitHub Actions / nodejs-ci (20.8)

Missing semicolon
});
// -----------------------------------
// Private Methods
// -----------------------------------
let close;
const dialogPromise = () => new Promise((resolve) => (close = resolve));
const open = () => {
state.active = true;
return dialogPromise();
};
const reset = () => {
state.tabs.splice(0),
state.active = false;
state.activeTabName = '';
state.confirmText = 'Ok';
state.cancelText = 'Cancel';
state.removeText = '';
state.message = '';
};
function toggleTab(newActiveTabName) {
console.log(`INPUTDialog - Toggle Tab New Active Tab Name- ${newActiveTabName}`);
// console.log(state);
state.activeTabName = newActiveTabName;
// console.log(state);
}
// -----------------------------------
// Public Methods
// -----------------------------------
function confirmText(text) {
state.confirmText = text;
return this;
}
function cancelText(text) {
state.cancelText = text;
return this;
}
function removeText(text) {
state.remove = text;
return this;
}
function message(text) {
state.message = text;
return this;
}
function file(includeComments=false, includeIcon='file', fileTypesAccept='.json') {
console.log('InputDialog:File - Called Beginning');
const fileInput = {
name: 'input-dialog-upload-file',
icon: includeIcon,
input: {
data: '',
...(includeComments) && {comments: ''},
type: 'file',
},
props: {
fileTypeAccept: fileTypesAccept,
},
};
state.tabs.push(fileInput);
state.activeTabName = fileInput.name;
console.log('InputDialog:File - Call Ended, State Before');
return this;
}
function url(includeComments=false, includeName=false) {
const attachUrlInput = {
name: 'input-dialog-attach-url',
icon: 'link',
input: {
...(includeName) && {name: ''},
data: '',
...(includeComments) && {comments: ''},
type: 'link',
},
props: {
},
};
state.tabs.push(attachUrlInput);
state.activeTabName = attachUrlInput.name;
return this;
}
function edit(attachmentInput) {
const attachUrlInput = {
name: attachmentInput.type == 'link' ? 'input-dialog-attach-url' : 'input-dialog-upload-file',
icon: attachmentInput.type == 'link' ? 'link' : 'file',
input: {
...attachmentInput,
data: attachmentInput.type == 'file' ? {name: attachmentInput.name} : attachmentInput.data,
},
};
state.tabs.push(attachUrlInput);
state.activeTabName = attachUrlInput.name;
return this;
}
function prompt() {
console.log('InputDialog:prompt called');
if (0 == state.tabs.length) {
throw Error('InputDialog requires either a file or url to be configured for render');
}
return open();
}
function cancel() {
close(false);
reset();
}
function confirmation(userInput) {
close(userInput);
reset();
}
function remove() {
close('DELETE');
reset();
}
function updateActiveTabInput(updatedUserInput) {
const tab = state.tabs.find((tab) => tab.name === state.activeTabName);
tab.input = updatedUserInput;
}
// const operations = {
// confirmText,
// cancelText,
// removeText,
// message,
// file,
// url,
// edit,
// prompt,
// cancel,
// confirmation,
// remove,
// activeTab,
// updateActiveTabInput,
// };
defineExpose({
confirmText,
cancelText,
removeText,
message,
file,
url,
edit,
prompt,
cancel,
confirmation,
remove,
activeTab,
updateActiveTabInput,
});
</script>

<style scoped>
Expand Down
Loading

0 comments on commit a68f40e

Please sign in to comment.