Setup Screen: Address feedback on UX

This commit is contained in:
Francesco Siddi 2022-07-21 16:10:18 +02:00
parent b74c8558cf
commit 78af4fae61

View File

@ -7,7 +7,7 @@
v-for="step in 4" :key="step" v-for="step in 4" :key="step"
@click="jumpToStep(step)" @click="jumpToStep(step)"
:class="{ :class="{
current: step == currentSetupStep, current: step == currentSetupStep,
done: step < currentSetupStep, done: step < currentSetupStep,
disabled: step > overallSetupStep, disabled: step > overallSetupStep,
}" }"
@ -37,11 +37,11 @@
</ul> </ul>
<p>More information is available on the online documentation at flamenco.blender.org.</p> <p>More information is available on the online documentation at flamenco.blender.org.</p>
</step-item> </step-item>
<step-item <step-item
v-show="currentSetupStep == 2" v-show="currentSetupStep == 2"
@next-clicked="nextStep" @next-clicked="nextStepAfterCheckSharedStoragePath"
@back-clicked="prevStep" @back-clicked="prevStep"
:is-next-clickable="sharedStorageCheckResult !=null && sharedStorageCheckResult.is_usable" :is-next-clickable="sharedStoragePath.length > 0"
title="Shared Storage" title="Shared Storage"
> >
<p>Please specify a storage path (or drive), where you want to store your Flamenco data. <p>Please specify a storage path (or drive), where you want to store your Flamenco data.
@ -57,24 +57,23 @@
<p>Using a service like Syncthing, ownCloud, or Dropbox for <p>Using a service like Syncthing, ownCloud, or Dropbox for
this is not recommended, as Flamenco can't coordinate data synchronization.</p> this is not recommended, as Flamenco can't coordinate data synchronization.</p>
<input <input
v-model="sharedStoragePath" v-model="sharedStoragePath"
@input="checkSharedStoragePath" @keyup.enter="nextStepAfterCheckSharedStoragePath"
@keyup.enter="nextStepAfterStoragePath" type="text"
type="text"
placeholder="Shared Storage Path" placeholder="Shared Storage Path"
class="path-input" class="path-input"
> >
<p v-if="sharedStorageCheckResult != null" <p v-if="sharedStorageCheckResult != null"
:class="{ :class="{
'check-ok': sharedStorageCheckResult.is_usable, 'check-ok': sharedStorageCheckResult.is_usable,
'check-failed': !sharedStorageCheckResult.is_usable 'check-failed': !sharedStorageCheckResult.is_usable
}"> }">
{{ sharedStorageCheckResult.cause }} {{ sharedStorageCheckResult.cause }}
</p> </p>
<p v-else></p> <p v-else></p>
</step-item> </step-item>
<step-item <step-item
v-show="currentSetupStep == 3" v-show="currentSetupStep == 3"
@next-clicked="nextStep" @next-clicked="nextStep"
@back-clicked="prevStep" @back-clicked="prevStep"
@ -84,57 +83,82 @@
<div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div> <div v-if="isBlenderExeFinding" class="is-in-progress">Looking for Blender installs...</div>
<fieldset v-if="allBlenders.length > 1"> <p v-if="autoFoundBlenders.length === 0">Provide a path to Blender. This path should be accessible by all Workers. If your rendering
<legend>Choose which Blender to use:</legend> setup features operating systems different form the one you are currently using, you can
<div v-for="(blender, index) in allBlenders"> manually set up the other paths later.</p>
<label :for="'blender-'+index">
<input type="radio" v-model="selectedBlender" name="blender" :value="blender.path" :id="'blender-'+index"> <p v-else>Choose how a Worker should invoke the Blender command when performing a task.</p>
{{ blender.cause }}
<span <fieldset v-if="allBlenders.length >= 1">
:aria-label="blender.path" <label v-if="autoFoundBlenderPathEnvvar" for="blender-path_envvar">
data-microtip-position="top" <input type="radio" v-model="selectedBlender" name="blender" :value="autoFoundBlenderPathEnvvar" id="blender-path_envvar">
role="tooltip"> {{ sourceLabels[autoFoundBlenderPathEnvvar.source] }} <br>
[Path] <span>{{autoFoundBlenderPathEnvvar.path}}</span>
</span> <span
<span :aria-label="autoFoundBlenderPathEnvvar.cause"
:aria-label="sourceLabels[blender.source]" data-microtip-position="top"
data-microtip-position="top" role="tooltip">
role="tooltip"> [Command output]
[Source] </span>
</span> </label>
</label> <label v-if="autoFoundBlenderFileAssociation" for="blender-file_association">
</div> <input type="radio" v-model="selectedBlender" name="blender" :value="autoFoundBlenderFileAssociation" id="blender-file_association">
{{ sourceLabels[autoFoundBlenderFileAssociation.source] }} <br>
<span>{{autoFoundBlenderFileAssociation.path}}</span>
<span
:aria-label="autoFoundBlenderFileAssociation.cause"
data-microtip-position="top"
role="tooltip">
[Command output]
</span>
</label>
<label for="blender-input_path">
<input
type="radio"
v-model="selectedBlender"
name="blender"
:value="blenderFromInputPath"
id="blender-input_path"
>
{{ sourceLabels['input_path'] }} <br>
<span>
<input
@input="checkBlenderExePath"
v-model="customBlenderExe"
type="text"
placeholder="Blender Path"
class="path-input"
>
</span>
<p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
{{ blenderExeCheckResult.cause }}</p>
</label>
</fieldset> </fieldset>
<p v-if="allBlenders.length <= 1"> <div v-if="autoFoundBlenders.length === 0">
Provide a path to Blender. This path should be accessible by all Workers. If your rendering <input
setup features operating systems different form the one you are currently using, you can @input="checkBlenderExePath"
manually set up the other paths later. v-model="customBlenderExe"
</p> type="text"
<p v-else>Or provide an alternative command to try.</p> placeholder="Blender Path"
class="path-input"
>
<input <p v-if="isBlenderExeChecking" class="is-in-progress">Checking...</p>
@input="checkBlenderExePath"
v-model="customBlenderExe"
type="text"
placeholder="Blender Path"
class="path-input"
>
<div v-if="isBlenderExeChecking" class="is-in-progress">Checking...</div> <p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
{{ blenderExeCheckResult.cause }}</p>
<p v-if="blenderExeCheckResult != null && blenderExeCheckResult.is_usable" class="check-ok"> </div>
Found something, it is selected above.</p>
<p v-if="blenderExeCheckResult != null && !blenderExeCheckResult.is_usable" class="check-failed">
{{ blenderExeCheckResult.cause }}</p>
</step-item> </step-item>
<step-item <step-item
v-show="currentSetupStep == 4" v-show="currentSetupStep == 4"
@next-clicked="confirmWizard" @next-clicked="confirmWizard"
@back-clicked="prevStep" @back-clicked="prevStep"
next-label="Confirm" next-label="Confirm"
title="Review" title="Review"
:is-next-clickable="isConfigComplete" :is-next-clickable="setupConfirmIsClickable"
> >
<div v-if="isConfigComplete"> <div v-if="isConfigComplete">
<p>This is the configuration that will be used by Flamenco:</p> <p>This is the configuration that will be used by Flamenco:</p>
@ -194,9 +218,9 @@ function debounce(func, wait, immediate) {
export default { export default {
name: 'FirstTimeWizardView', name: 'FirstTimeWizardView',
components: { components: {
NotificationBar,
UpdateListener, UpdateListener,
StepItem, StepItem,
NotificationBar,
}, },
data: () => ({ data: () => ({
sharedStoragePath: "", sharedStoragePath: "",
@ -213,9 +237,9 @@ export default {
isBlenderExeChecking: false, isBlenderExeChecking: false,
blenderExeCheckResult: null, // api.BlenderPathCheckResult blenderExeCheckResult: null, // api.BlenderPathCheckResult
sourceLabels: { sourceLabels: {
file_association: "This Blender runs when you double-click a .blend file.", file_association: "Blender that runs when you double-click a .blend file.",
path_envvar: "This Blender was found on the $PATH environment.", path_envvar: "Blender that was found on the $PATH environment.",
input_path: "You pointed Flamenco to this executable.", input_path: "Another Blender executable.",
}, },
isConfirming: false, isConfirming: false,
isConfirmed: false, isConfirmed: false,
@ -238,6 +262,22 @@ export default {
isConfigComplete() { isConfigComplete() {
return this.isSharedStorageValid && this.isSelectedBlenderValid; return this.isSharedStorageValid && this.isSelectedBlenderValid;
}, },
autoFoundBlenderPathEnvvar() {
return this.autoFoundBlenders.find(b => b.source === 'path_envvar');
},
autoFoundBlenderFileAssociation() {
return this.autoFoundBlenders.find(b => b.source === 'file_association');
},
blenderFromInputPath() {
return this.allBlenders.find(b => b.source === 'input_path');
},
setupConfirmIsClickable() {
if (this.isConfirming || this.isConfirmed) {
return false;
} else {
return true;
}
}
}, },
mounted() { mounted() {
this.findBlenderExePath(); this.findBlenderExePath();
@ -251,20 +291,22 @@ export default {
onSIODisconnected(reason) { onSIODisconnected(reason) {
}, },
checkSharedStoragePath() { nextStepAfterCheckSharedStoragePath() {
const pathCheck = new PathCheckInput(this.cleanSharedStoragePath); const pathCheck = new PathCheckInput(this.cleanSharedStoragePath);
console.log("requesting path check:", pathCheck); console.log("requesting path check:", pathCheck);
this.metaAPI.checkSharedStoragePath({ pathCheckInput: pathCheck }) return this.metaAPI.checkSharedStoragePath({ pathCheckInput: pathCheck })
.then((result) => { .then((result) => {
console.log("Storage path check result:", result); console.log("Storage path check result:", result);
this.sharedStorageCheckResult = result; this.sharedStorageCheckResult = result;
if (this.isSharedStorageValid) {
this.nextStep();
}
}) })
.catch((error) => { .catch((error) => {
console.log("Error checking storage path:", error); console.log("Error checking storage path:", error);
}) })
}, },
findBlenderExePath() { findBlenderExePath() {
this.isBlenderExeFinding = true; this.isBlenderExeFinding = true;
this.autoFoundBlenders = []; this.autoFoundBlenders = [];
@ -305,6 +347,8 @@ export default {
this.blenderExeCheckResult = result; this.blenderExeCheckResult = result;
if (result.is_usable) { if (result.is_usable) {
this.selectedBlender = result; this.selectedBlender = result;
} else if (this.selectedBlender.source === 'input_path') {
this.selectedBlender = null;
} }
this._refreshAllBlenders(); this._refreshAllBlenders();
}) })
@ -324,12 +368,6 @@ export default {
} }
}, },
nextStepAfterStoragePath() {
if (this.isSharedStorageValid) {
this.nextStep();
}
},
nextStep() { nextStep() {
if (this.overallSetupStep <= this.currentSetupStep) { if (this.overallSetupStep <= this.currentSetupStep) {
this.overallSetupStep = this.currentSetupStep + 1; this.overallSetupStep = this.currentSetupStep + 1;
@ -377,6 +415,10 @@ export default {
</script> </script>
<style> <style>
label {
display: block;
}
.progress { .progress {
--wiz-progress-indicator-size: 8px; --wiz-progress-indicator-size: 8px;
--wiz-progress-indicator-border-width: 2px; --wiz-progress-indicator-border-width: 2px;