UPD: Refactor components
This commit is contained in:
@@ -88,7 +88,7 @@ import {
|
||||
MenubarTrigger,
|
||||
MenubarContent,
|
||||
} from '@/components/ui/menubar/index.js'
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { X, Square, Minus } from 'lucide-vue-next'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { ChevronLeft } from 'lucide-vue-next'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible/index.js'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
|
||||
import { ref } from 'vue'
|
||||
import { Switch } from '@/components/ui/switch/index.js'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
|
||||
const collapse = ref(true)
|
||||
|
||||
@@ -12,10 +12,9 @@
|
||||
<HSVInput v-model="options[currentOption].color" class="relative z-20" />
|
||||
</template>
|
||||
<script setup>
|
||||
import HSVInput from '@/components/config/HSVInput.vue'
|
||||
import HSVInput from '@/components/common/HSVInput.vue'
|
||||
import Color from 'color'
|
||||
import { onBeforeMount, reactive, ref } from 'vue'
|
||||
import TabSelect from '@/components/config/TabSelect.vue'
|
||||
|
||||
const currentOption = ref(null)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { CircleDot } from 'lucide-vue-next'
|
||||
import TabSelectButton from '@/components/config/TabSelectButton.vue'
|
||||
import TabSelectButton from '@/components/common/TabSelectButton.vue'
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
|
||||
const model = defineModel({
|
||||
@@ -16,7 +16,7 @@
|
||||
</button>
|
||||
</template>
|
||||
<script setup>
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
|
||||
defineEmits(['select'])
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="showTabs" class="flex">
|
||||
<!-- TODO: Remove later if not needed -->
|
||||
<button
|
||||
v-for="(option, key) in store.currentConfigPages" :key="key"
|
||||
class="flex-1 h-12 items-center text-center group px-3 font-heading"
|
||||
:class="key===store.currentConfigPage ? 'bg-zinc-900': 'hover:bg-zinc-800 text-zinc-200'"
|
||||
@click="store.setCurrentConfigPage(key)">
|
||||
{{ $t(option.titleKey) }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="grow overflow-y-auto">
|
||||
<component :is="store.currentConfigComponent" />
|
||||
</div>
|
||||
@@ -9,4 +19,11 @@
|
||||
import { useStore } from '@/store'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
defineProps({
|
||||
showTabs: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -5,8 +5,8 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { Lightbulb } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import PaletteInput from '@/components/config/PaletteInput.vue'
|
||||
import ConfigSection from '@/components/common/ConfigSection.vue'
|
||||
import PaletteInput from '@/components/common/PaletteInput.vue'
|
||||
import Color from 'color'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -43,16 +43,16 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { AudioLines, AudioWaveform, GaugeCircle, Lightbulb } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import PaletteInput from '@/components/config/PaletteInput.vue'
|
||||
import ConfigSection from '@/components/common/ConfigSection.vue'
|
||||
import PaletteInput from '@/components/common/PaletteInput.vue'
|
||||
import Color from 'color'
|
||||
import { computed, ref } from 'vue'
|
||||
import TabSelect from '@/components/config/TabSelect.vue'
|
||||
import { ref } from 'vue'
|
||||
import TabSelect from '@/components/common/TabSelect.vue'
|
||||
import FdIcon from '@/assets/icons/iconFineDetents.svg'
|
||||
import CdIcon from '@/assets/icons/iconCoarseDetents.svg'
|
||||
import VfIcon from '@/assets/icons/iconViscousRotation.svg'
|
||||
import RcIcon from '@/assets/icons/iconReturnToCenter.svg'
|
||||
import SteppedSlider from '@/components/config/SteppedSlider.vue'
|
||||
import SteppedSlider from '@/components/common/SteppedSlider.vue'
|
||||
|
||||
const feedbackType = ref('fineDetents') // TODO: replace with actual value
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import { Badge } from '@/components/ui/badge/index.js'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { ChevronRight } from 'lucide-vue-next'
|
||||
|
||||
const config_tabs = ref([
|
||||
@@ -40,14 +40,14 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { AudioLines, AudioWaveform, GaugeCircle } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import SteppedSlider from '@/components/config/SteppedSlider.vue'
|
||||
import ConfigSection from '@/components/common/ConfigSection.vue'
|
||||
import SteppedSlider from '@/components/common/SteppedSlider.vue'
|
||||
import { ref } from 'vue'
|
||||
import FdIcon from '@/assets/icons/iconFineDetents.svg'
|
||||
import CdIcon from '@/assets/icons/iconCoarseDetents.svg'
|
||||
import VfIcon from '@/assets/icons/iconViscousRotation.svg'
|
||||
import RcIcon from '@/assets/icons/iconReturnToCenter.svg'
|
||||
import TabSelect from '@/components/config/TabSelect.vue'
|
||||
import TabSelect from '@/components/common/TabSelect.vue'
|
||||
|
||||
const feedbackType = ref('fineDetents') // TODO: replace with actual value
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</button>
|
||||
</template>
|
||||
<script setup>
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { ArrowBigUp } from 'lucide-vue-next'
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { Lightbulb, PanelBottomClose, Circle, PanelBottom } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import PaletteInput from '@/components/config/PaletteInput.vue'
|
||||
import ConfigSection from '@/components/common/ConfigSection.vue'
|
||||
import PaletteInput from '@/components/common/PaletteInput.vue'
|
||||
import Color from 'color'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useStore } from '@/store.js'
|
||||
import { Slider } from '@/components/ui/slider/index.js'
|
||||
import { Slider } from '@/components/ui/slider'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
@@ -127,8 +127,8 @@
|
||||
</ConfigSection>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Badge } from '@/components/ui/badge/index.js'
|
||||
import { Tabs } from '@/components/ui/tabs/index.js'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Tabs } from '@/components/ui/tabs'
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
@@ -136,16 +136,16 @@ import {
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList, CommandSeparator,
|
||||
} from '@/components/ui/command/index.js'
|
||||
import { Slider } from '@/components/ui/slider/index.js'
|
||||
} from '@/components/ui/command'
|
||||
import { Slider } from '@/components/ui/slider'
|
||||
import { KeyboardMusic, Squircle, Keyboard, GaugeCircle, Play, Pause } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import ConfigSection from '@/components/common/ConfigSection.vue'
|
||||
import KeyO from '@/assets/icons/iconKeyOrange.svg'
|
||||
import Key from '@/assets/icons/iconKeyWhite.svg'
|
||||
import KeyG from '@/assets/icons/iconKeyGrey.svg'
|
||||
import KeyD from '@/assets/icons/iconKeyDark.svg'
|
||||
import { ref } from 'vue'
|
||||
import KeySelectButton from '@/components/config/KeySelectButton.vue'
|
||||
import KeySelectButton from '@/components/config/old/KeySelectButton.vue'
|
||||
|
||||
const selectedKey = ref('a') // TODO: replace with actual value
|
||||
|
||||
@@ -28,13 +28,13 @@
|
||||
</div>
|
||||
<button
|
||||
class="rounded-full outline-2 absolute h-[41.5%] top-[24.5%] aspect-square left-0 right-0 mx-auto transition-all"
|
||||
:class="{'outline outline-white': store.currentConfigPage==='knob',
|
||||
'hover:outline outline-zinc-400': store.currentConfigPage!=='knob'}"
|
||||
@click="store.setCurrentConfigPage('knob')" />
|
||||
:class="{'outline outline-white': store.selectedFeature==='knob',
|
||||
'hover:outline outline-zinc-400': store.selectedFeature!=='knob'}"
|
||||
@click="store.selectConfigFeature('knob')" />
|
||||
<DeviceKeys
|
||||
class="absolute w-[72.7%] top-[77.2%] gap-[2.8%] left-0 right-0 mx-auto"
|
||||
:selected="store.currentConfigPage"
|
||||
@select="store.setCurrentConfigPage" />
|
||||
:selected="store.selectedFeature"
|
||||
@select="store.selectConfigFeature" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -43,7 +43,7 @@ import RenderNano from '@/assets/images/renderNano.png'
|
||||
import LogoMidi from '@/assets/logos/logoMidi.svg'
|
||||
import DeviceBar from '@/components/device/DeviceBar.vue'
|
||||
import { useStore } from '@/store'
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import DeviceLEDRing from '@/components/device/DeviceLEDRing.vue'
|
||||
import gsap from 'gsap'
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { ChevronRight } from 'lucide-vue-next'
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { Check, Copy, PenLine, Trash2, X, GripHorizontal } from 'lucide-vue-next'
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { nextTick, ref } from 'vue'
|
||||
|
||||
defineEmits(['select', 'duplicate', 'delete'])
|
||||
|
||||
@@ -26,14 +26,14 @@
|
||||
</template>
|
||||
<script setup>
|
||||
import { Cable, Replace, Type } from 'lucide-vue-next'
|
||||
import ConfigSection from '@/components/config/ConfigSection.vue'
|
||||
import { Separator } from '@/components/ui/separator/index.js'
|
||||
import ConfigSection from '@/components/common/ConfigSection.vue'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import { ref } from 'vue'
|
||||
import UsbIcon from '@/assets/logos/logoUsb.svg'
|
||||
import MidiIcon from '@/assets/logos/logoMidi.svg'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import WIP from '@/components/WIP.vue'
|
||||
import TabSelect from '@/components/config/TabSelect.vue'
|
||||
import TabSelect from '@/components/common/TabSelect.vue'
|
||||
|
||||
const connectionType = ref('usb') // TODO: replace with actual value
|
||||
|
||||
@@ -84,10 +84,10 @@ import { Separator } from '@/components/ui/separator'
|
||||
import { ChevronRight, Plus, Search, ArrowLeft, List } from 'lucide-vue-next'
|
||||
import { computed, ref } from 'vue'
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible'
|
||||
import ScrambleText from '@/components/effects/ScrambleText.vue'
|
||||
import ScrambleText from '@/components/common/ScrambleText.vue'
|
||||
import { useStore } from '@/store.js'
|
||||
import ProfileButton from '@/components/profile/ProfileButton.vue'
|
||||
import ProfileConfig from '@/components/config/pages/ProfileConfig.vue'
|
||||
import ProfileConfig from '@/components/profile/ProfileConfig.vue'
|
||||
|
||||
defineProps({
|
||||
showFilter: {
|
||||
|
||||
91
src/store.js
91
src/store.js
@@ -19,8 +19,9 @@ import { createPinia, defineStore } from 'pinia'
|
||||
import Axios from 'axios'
|
||||
import schema from '@/data/profileSchema.json'
|
||||
import Ajv from 'ajv'
|
||||
import KnobConfig from '@/components/config/pages/KnobConfig.vue'
|
||||
import KeyConfig from '@/components/config/pages/KeyConfig.vue'
|
||||
import KnobConfig from '@/components/config/knob/KnobConfig.vue'
|
||||
import KeyConfig from '@/components/config/keys/KeyConfig.vue'
|
||||
import WIP from '@/components/WIP.vue'
|
||||
|
||||
const ajv = new Ajv()
|
||||
|
||||
@@ -31,38 +32,60 @@ export const useStore = defineStore('main', {
|
||||
profiles: [],
|
||||
selectedProfileId: null,
|
||||
connected: false,
|
||||
currentConfigPage: 'knob',
|
||||
selectedFeature: 'knob',
|
||||
currentConfigPage: 'mapping',
|
||||
configPages: {
|
||||
knob: {
|
||||
mapping: {
|
||||
titleKey: 'config_options.mapping_configuration.title',
|
||||
component: KnobConfig,
|
||||
},
|
||||
feedback: {
|
||||
titleKey: 'config_options.feedback_designer.title',
|
||||
component: KnobConfig,
|
||||
},
|
||||
lighting: {
|
||||
titleKey: 'config_options.light_designer.title',
|
||||
component: KnobConfig,
|
||||
},
|
||||
},
|
||||
key: {
|
||||
mapping: {
|
||||
titleKey: 'config_options.mapping_configuration.title',
|
||||
component: KeyConfig,
|
||||
},
|
||||
feedback: {
|
||||
titleKey: 'config_options.feedback_designer.title',
|
||||
component: KeyConfig,
|
||||
},
|
||||
lighting: {
|
||||
titleKey: 'config_options.light_designer.title',
|
||||
component: KeyConfig,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
profileIds: (state) => state.profiles.map(p => p.id),
|
||||
selectedProfile: (state) => state.profiles.find(p => p.id === state.selectedProfileId),
|
||||
currentConfigComponent: (state) => {
|
||||
switch (state.currentConfigPage) {
|
||||
case 'knob':
|
||||
return KnobConfig
|
||||
case 'a':
|
||||
return KeyConfig
|
||||
case 'b':
|
||||
return KeyConfig
|
||||
case 'c':
|
||||
return KeyConfig
|
||||
case 'd':
|
||||
return KeyConfig
|
||||
default:
|
||||
return KnobConfig
|
||||
}
|
||||
},
|
||||
},
|
||||
getters:
|
||||
{
|
||||
profileIds: (state) => state.profiles.map(p => p.id),
|
||||
selectedProfile: (state) => state.profiles.find(p => p.id === state.selectedProfileId),
|
||||
currentConfigFeature: (state) => ['a', 'b', 'c', 'd'].includes(state.selectedFeature) ? 'key' : state.selectedFeature,
|
||||
currentConfigComponent: (state) => state.configPages[state.currentConfigFeature][state.currentConfigPage]?.component || WIP,
|
||||
currentConfigPages: (state) => state.configPages[state.currentConfigFeature] || {},
|
||||
}
|
||||
,
|
||||
actions: {
|
||||
selectProfile(id) {
|
||||
if (!this.profileIds.includes(id)) return false
|
||||
this.selectedProfileId = id
|
||||
return true
|
||||
},
|
||||
}
|
||||
,
|
||||
addProfile() {
|
||||
console.log('addProfile is not implemented')
|
||||
},
|
||||
}
|
||||
,
|
||||
duplicateProfile(id) {
|
||||
const originalProfile = this.profiles.find(p => p.id === id)
|
||||
const newProfile = JSON.parse(JSON.stringify(originalProfile))
|
||||
@@ -71,7 +94,8 @@ export const useStore = defineStore('main', {
|
||||
this.profiles.push(newProfile)
|
||||
this.selectedProfileId = newProfile.id
|
||||
return newProfile.id
|
||||
},
|
||||
}
|
||||
,
|
||||
deleteProfile(id) {
|
||||
const index = this.profiles.findIndex(p => p.id === id)
|
||||
if (index >= 0) {
|
||||
@@ -82,7 +106,8 @@ export const useStore = defineStore('main', {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
},
|
||||
}
|
||||
,
|
||||
fetchProfiles() {
|
||||
Axios.get('http://localhost:3001/profiles').then((res) => {
|
||||
const profiles = res.data
|
||||
@@ -107,7 +132,8 @@ export const useStore = defineStore('main', {
|
||||
}).catch((err) => {
|
||||
console.error(err)
|
||||
})
|
||||
},
|
||||
}
|
||||
,
|
||||
newProfileName(originalName = '') {
|
||||
let name = originalName
|
||||
let i = 1
|
||||
@@ -115,7 +141,8 @@ export const useStore = defineStore('main', {
|
||||
name = `${originalName} (${i++})`
|
||||
}
|
||||
return name
|
||||
},
|
||||
}
|
||||
,
|
||||
newProfileId(originalId = '') {
|
||||
let id = originalId
|
||||
if (originalId) {
|
||||
@@ -128,6 +155,12 @@ export const useStore = defineStore('main', {
|
||||
} while (this.profileIds.includes(id))
|
||||
}
|
||||
return id
|
||||
}
|
||||
,
|
||||
selectConfigFeature(feature) {
|
||||
this.selectedFeature = feature
|
||||
if (!this.configPages[this.currentConfigFeature])
|
||||
this.setCurrentConfigPage('mapping')
|
||||
},
|
||||
setCurrentConfigPage(page) {
|
||||
this.currentConfigPage = page
|
||||
|
||||
Reference in New Issue
Block a user