Skip to content

Commit

Permalink
Merge pull request galaxyproject#17441 from itisAliRH/commons-composi…
Browse files Browse the repository at this point in the history
…tion-ts-refactor

Refactor Common components
  • Loading branch information
guerler authored Feb 12, 2024
2 parents 8476819 + 02f096e commit 54f661c
Show file tree
Hide file tree
Showing 17 changed files with 544 additions and 407 deletions.
6 changes: 5 additions & 1 deletion client/src/components/Common/Abbreviation.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<script setup lang="ts">
const props = defineProps<{ explanation: string }>();
interface Props {
explanation: string;
}
const props = defineProps<Props>();
</script>

<template>
Expand Down
68 changes: 30 additions & 38 deletions client/src/components/Common/ButtonSpinner.vue
Original file line number Diff line number Diff line change
@@ -1,53 +1,45 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faPlay, faSpinner } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BButton } from "bootstrap-vue";
library.add(faPlay, faSpinner);
interface Props {
title: string;
wait?: boolean;
tooltip?: string;
disabled?: boolean;
}
withDefaults(defineProps<Props>(), {
wait: false,
tooltip: undefined,
disabled: false,
});
</script>

<template>
<b-button
<BButton
v-if="wait"
v-b-tooltip.hover.bottom
disabled
variant="info"
title="Please Wait..."
class="d-flex flex-nowrap align-items-center text-nowrap">
<FontAwesomeIcon icon="spinner" class="mr-2" spin />{{ title }}
</b-button>
<b-button
<FontAwesomeIcon :icon="faSpinner" class="mr-2" spin />
{{ title }}
</BButton>
<BButton
v-else
v-b-tooltip.hover.bottom
variant="primary"
class="d-flex flex-nowrap align-items-center text-nowrap"
:title="tooltip"
:disabled="disabled"
@click="$emit('onClick')">
<FontAwesomeIcon icon="play" class="mr-2" />{{ title }}
</b-button>
<FontAwesomeIcon :icon="faPlay" class="mr-2" />
{{ title }}
</BButton>
</template>
<script>
import { library } from "@fortawesome/fontawesome-svg-core";
import { faPlay, faSpinner } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
library.add(faSpinner);
library.add(faPlay);
export default {
components: {
FontAwesomeIcon,
},
props: {
title: {
type: String,
required: true,
},
wait: {
type: Boolean,
default: false,
},
tooltip: {
type: String,
default: null,
},
disabled: {
type: Boolean,
default: false,
},
},
};
</script>
202 changes: 107 additions & 95 deletions client/src/components/Common/DelayedInput.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,96 @@
<script setup lang="ts">
import { library } from "@fortawesome/fontawesome-svg-core";
import { faAngleDoubleDown, faAngleDoubleUp, faSpinner, faTimes } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { BButton, BFormInput, BInputGroup, BInputGroupAppend } from "bootstrap-vue";
import { onMounted, ref, watch } from "vue";
import localize from "@/utils/localization";
library.add(faAngleDoubleDown, faAngleDoubleUp, faSpinner, faTimes);
interface Props {
query?: string;
delay?: number;
loading?: boolean;
placeholder?: string;
showAdvanced?: boolean;
enableAdvanced?: boolean;
}
const props = withDefaults(defineProps<Props>(), {
query: "",
delay: 1000,
loading: false,
placeholder: "Enter your search term here.",
showAdvanced: false,
enableAdvanced: false,
});
const emit = defineEmits<{
(e: "change", query: string): void;
(e: "onToggle", showAdvanced: boolean): void;
}>();
const queryInput = ref<string>();
const queryCurrent = ref<string>();
const queryTimer = ref<any>(null);
const titleClear = ref("Clear Search (esc)");
const titleAdvanced = ref("Toggle Advanced Search");
const toolInput = ref<HTMLInputElement | null>(null);
function clearTimer() {
if (queryTimer.value) {
clearTimeout(queryTimer.value);
}
}
function delayQuery(query: string) {
clearTimer();
if (query) {
queryTimer.value = setTimeout(() => {
setQuery(query);
}, props.delay);
} else {
setQuery(query);
}
}
function setQuery(queryNew: string) {
clearTimer();
if (queryCurrent.value !== queryInput.value || queryCurrent.value !== queryNew) {
queryCurrent.value = queryInput.value = queryNew;
emit("change", queryCurrent.value);
}
}
function clearBox() {
setQuery("");
toolInput.value?.focus();
}
function onToggle() {
emit("onToggle", !props.showAdvanced);
}
watch(
() => props.query,
(newQuery) => {
setQuery(newQuery);
}
);
onMounted(() => {
if (props.query) {
setQuery(props.query);
}
});
</script>

<template>
<b-input-group>
<b-input
<BInputGroup>
<BFormInput
ref="toolInput"
v-model="queryInput"
class="search-query"
Expand All @@ -11,111 +101,33 @@
@input="delayQuery"
@change="setQuery"
@keydown.esc="setQuery('')" />
<b-input-group-append>
<b-button

<BInputGroupAppend>
<BButton
v-if="enableAdvanced"
v-b-tooltip.hover.bottom.noninteractive
aria-haspopup="true"
size="sm"
:pressed="showAdvanced"
:variant="showAdvanced ? 'info' : 'secondary'"
:title="titleAdvanced | l"
:title="localize(titleAdvanced)"
data-description="toggle advanced search"
@click="onToggle">
<icon v-if="showAdvanced" fixed-width icon="angle-double-up" />
<icon v-else fixed-width icon="angle-double-down" />
</b-button>
<b-button
<FontAwesomeIcon v-if="showAdvanced" fixed-width :icon="faAngleDoubleUp" />
<FontAwesomeIcon v-else fixed-width :icon="faAngleDoubleDown" />
</BButton>

<BButton
v-b-tooltip.hover.bottom.noninteractive
aria-haspopup="true"
class="search-clear"
size="sm"
:title="titleClear | l"
:title="localize(titleClear)"
data-description="reset query"
@click="clearBox">
<icon v-if="loading" fixed-width icon="spinner" spin />
<icon v-else fixed-width icon="times" />
</b-button>
</b-input-group-append>
</b-input-group>
<FontAwesomeIcon v-if="loading" fixed-width :icon="faSpinner" spin />
<FontAwesomeIcon v-else fixed-width :icon="faTimes" />
</BButton>
</BInputGroupAppend>
</BInputGroup>
</template>
<script>
export default {
props: {
query: {
type: String,
default: "",
},
loading: {
type: Boolean,
default: false,
},
placeholder: {
type: String,
default: "Enter your search term here.",
},
delay: {
type: Number,
default: 1000,
},
enableAdvanced: {
type: Boolean,
default: false,
},
showAdvanced: {
type: Boolean,
default: false,
},
},
data() {
return {
queryInput: null,
queryTimer: null,
queryCurrent: null,
titleClear: "Clear Search (esc)",
titleAdvanced: "Toggle Advanced Search",
};
},
watch: {
query(queryNew) {
this.setQuery(queryNew);
},
},
created() {
if (this.query) {
this.setQuery(this.query);
}
},
methods: {
clearTimer() {
if (this.queryTimer) {
clearTimeout(this.queryTimer);
}
},
delayQuery(query) {
this.clearTimer();
if (query) {
this.queryTimer = setTimeout(() => {
this.setQuery(query);
}, this.delay);
} else {
this.setQuery(query);
}
},
setQuery(queryNew) {
this.clearTimer();
if (this.queryCurrent !== this.queryInput || this.queryCurrent !== queryNew) {
this.queryCurrent = this.queryInput = queryNew;
this.$emit("change", this.queryCurrent);
}
},
clearBox() {
this.setQuery("");
this.$refs.toolInput.focus();
},
onToggle() {
this.$emit("onToggle", !this.showAdvanced);
},
},
};
</script>
2 changes: 2 additions & 0 deletions client/src/components/Common/ExportForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ const doExport = () => {
:require-writable="true"
:filter-options="defaultExportFilterOptions" />
</BFormGroup>

<BFormGroup id="fieldset-name" label-for="name" :description="nameDescription" class="mt-3">
<BFormInput id="name" v-model="name" :placeholder="namePlaceholder" required />
</BFormGroup>

<BRow align-h="end">
<BCol>
<BButton
Expand Down
8 changes: 8 additions & 0 deletions client/src/components/Common/ExportRDMForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ function clearInputs() {

<BFormRadioGroup v-model="exportChoice" class="export-radio-group">
<BFormRadio id="radio-new" v-localize name="exportChoice" value="new"> Export to new record </BFormRadio>

<BFormRadio id="radio-existing" v-localize name="exportChoice" value="existing">
Export to existing draft record
</BFormRadio>
Expand All @@ -98,14 +99,17 @@ function clearInputs() {
<b>{{ newEntry.name }}</b>
<span v-localize> draft record has been created in the repository.</span>
</p>

<p v-if="newEntry.external_link">
You can preview the record in the repository, further edit its metadata and decide when to
publish it at
<ExternalLink :href="newEntry.external_link">
<b>{{ newEntry.external_link }}</b>
</ExternalLink>
</p>

<p v-localize>Please use the button below to upload the exported {{ props.what }} to the record.</p>

<BButton
id="export-button-new-record"
v-localize
Expand All @@ -130,6 +134,7 @@ function clearInputs() {
:require-writable="true"
:filter-options="includeOnlyRDMCompatible" />
</BFormGroup>

<BFormGroup
id="fieldset-record-name"
label-for="record-name"
Expand All @@ -141,9 +146,11 @@ function clearInputs() {
:placeholder="recordNamePlaceholder"
required />
</BFormGroup>

<p v-localize>
You need to create the new record in a repository before exporting the {{ props.what }} to it.
</p>

<BButton
id="create-record-button"
v-localize
Expand All @@ -167,6 +174,7 @@ function clearInputs() {
:require-writable="true"
:filter-options="includeOnlyRDMCompatible" />
</BFormGroup>

<BButton
id="export-button-existing-record"
v-localize
Expand Down
Loading

0 comments on commit 54f661c

Please sign in to comment.