Add wizard component [SCI-10035]

This commit is contained in:
Anton 2024-01-19 20:33:34 +01:00
parent bd48ae1d07
commit 97c155f626
8 changed files with 268 additions and 1 deletions

View file

@ -0,0 +1,56 @@
import { createApp } from 'vue/dist/vue.esm-bundler.js';
import { shallowRef } from 'vue';
import WizardModal from '../../../vue/shared/wizard_modal.vue';
import Step1 from './wizard_steps/step_1.vue';
import Step2 from './wizard_steps/step_2.vue';
import Step3 from './wizard_steps/step_3.vue';
import { mountWithTurbolinks } from '../helpers/turbolinks.js';
const app = createApp({
components: {
Step1,
Step2,
Step3
},
methods: {
fireAlert() {
alert('Fired!');
}
},
data() {
return {
wizardConfig: {
title: 'Wizard steps',
subtitle: 'Wizard subtitle description',
steps: [
{
id: 'step1',
icon: 'sn-icon sn-icon-open',
label: 'Step 1',
component: shallowRef(Step1)
},
{
id: 'step2',
icon: 'sn-icon sn-icon-edit',
label: 'Step 2',
component: shallowRef(Step2)
},
{
id: 'step3',
icon: 'sn-icon sn-icon-inventory',
label: 'Step 3',
component: shallowRef(Step3)
}
]
},
wizardParams: {
text: 'Some text'
},
showWizard: false
};
}
});
app.component('WizardModal', WizardModal);
app.config.globalProperties.i18n = window.I18n;
mountWithTurbolinks(app, '#modals');

View file

@ -0,0 +1,37 @@
<template>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<i class="sn-icon sn-icon-close"></i>
</button>
<h4 class="modal-title truncate flex items-center gap-4">
Step 1 actions
</h4>
</div>
<div class="modal-body grow">
You can add any custom html here or render params like this:
{{ params }}
</div>
<div class="modal-footer">
<button class="btn btn-light" @click="$emit('close')">Cancel</button>
<button class="btn btn-primary" @click="$emit('next')">Next</button>
</div>
</template>
<script>
export default {
emits: ['close', 'next', 'back'],
name: 'Step1',
props: {
params: {
type: Object,
required: true
},
wizardComponent: {
type: Object,
required: true
}
}
};
</script>

View file

@ -0,0 +1,41 @@
<template>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<i class="sn-icon sn-icon-close"></i>
</button>
<h4 class="modal-title truncate flex items-center gap-4">
Step 2 actions
</h4>
</div>
<div class="modal-body grow">
All steps have access to shared params
<input
type="text"
class="form-control"
placeholder="Type something"
v-model="params.text"/>
</div>
<div class="modal-footer">
<button class="btn btn-light" @click="$emit('back')">Back</button>
<button class="btn btn-primary" @click="$emit('next')">Next</button>
</div>
</template>
<script>
export default {
emits: ['back', 'next', 'close'],
name: 'Step2',
props: {
params: {
type: Object,
required: true
},
wizardComponent: {
type: Object,
required: true
}
}
};
</script>

View file

@ -0,0 +1,42 @@
<template>
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<i class="sn-icon sn-icon-close"></i>
</button>
<h4 class="modal-title truncate flex items-center gap-4">
Step 3 actions
</h4>
</div>
<div class="modal-body grow">
Our params - {{ params }}<br>
If you want emit action use wizardComponent
<br>
<br>
<br>
<button class="btn btn-danger" @click="wizardComponent.$emit('alert')">Launch alert</button>
</div>
<div class="modal-footer">
<button class="btn btn-light" @click="$emit('back')">Back</button>
<button class="btn btn-primary" @click="$emit('close')">Apply</button>
</div>
</template>
<script>
export default {
emits: ['back', 'close', 'alert', 'next'],
name: 'Step3',
props: {
params: {
type: Object,
required: true
},
wizardComponent: {
type: Object,
required: true
}
}
};
</script>

View file

@ -0,0 +1,73 @@
<template>
<div ref="modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog !w-[900px]" role="document">
<div class="modal-content !p-0 grid grid-cols-3">
<div class="bg-sn-super-light-grey p-6 mb-1.5">
<h3 class="mb-1.5">{{ config.title }}</h3>
<div v-if="config.subtitle" class="text-sn-dark-grey">
{{ config.subtitle }}
</div>
<div class="flex flex-col mt-4">
<div v-for="(step, index) in config.steps" :key="step.id">
<div v-if="index > 0"
class="ml-0.5 left-4 relative h-8 w-0 border border-r-0 border-solid"
:class="{
'!border-sn-dark-grey': index <= activeStep,
'!border-sn-sleepy-grey': index > activeStep
}"
></div>
<div class="flex items-center gap-3">
<div class="rounded bg-white border border-sn-sleepy-grey p-1.5">
<i :class="step.icon"></i>
</div>
<span
class="font-bold text-xs"
:class="{
'text-sn-dark-grey': index <= activeStep,
'text-sn-grey': index > activeStep
}"
>
{{ step.label }}
</span>
</div>
</div>
</div>
</div>
<div class="col-span-2 p-6 flex flex-col">
<component
:is="config.steps[activeStep].component"
:params="params"
:wizardComponent="this"
@close="close"
@back="activeStep -= 1"
@next="activeStep += 1"
/>
</div>
</div>
</div>
</div>
</template>
<script>
import modalMixin from './modal_mixin';
export default {
name: 'WizardModal',
props: {
params: {
type: Object,
required: true
},
config: {
type: Object,
required: true
}
},
mixins: [modalMixin],
data() {
return {
activeStep: 0
};
}
};
</script>

View file

@ -0,0 +1,16 @@
<div>
<h1>Modals</h1>
<div id="modals" class="flex items-center gap-4 flex-wrap mt-6">
<button @click="showWizard = true" class="btn btn-primary">Show Wizard Modal</button>
<wizard-modal
v-if="showWizard"
@close="showWizard = false"
@alert="fireAlert"
:params="wizardParams"
:config="wizardConfig"
/>
</div>
</div>
<%= javascript_include_tag 'vue_design_system_modals' %>

View file

@ -0,0 +1 @@
<%= render partial: 'modals' %>

View file

@ -49,7 +49,8 @@ const entryList = {
vue_components_manage_stock_value_modal: './app/javascript/packs/vue/manage_stock_value_modal.js',
vue_legacy_datetime_picker: './app/javascript/packs/vue/legacy/datetime_picker.js',
vue_open_locally_menu: './app/javascript/packs/vue/open_locally_menu.js',
vue_scinote_edit_download: './app/javascript/packs/vue/scinote_edit_download.js'
vue_scinote_edit_download: './app/javascript/packs/vue/scinote_edit_download.js',
vue_design_system_modals: './app/javascript/packs/vue/design_system/modals.js'
}
// Engine pack loading based on https://github.com/rails/webpacker/issues/348#issuecomment-635480949