Split lists into their own components

This commit is contained in:
James Lyne 2022-01-12 13:20:23 +00:00
parent 8d8c242622
commit 4b834aa0b0
13 changed files with 172 additions and 43 deletions

View File

@ -30,21 +30,21 @@
</button> </button>
</header> </header>
<div class="sidebar__content" @keydown="handleSidebarKeydown"> <div class="sidebar__content" @keydown="handleSidebarKeydown">
<ServerList v-if="serverCount > 1" v-show="mapsVisible"></ServerList> <ServersSection v-if="serverCount > 1" v-show="mapsVisible"></ServersSection>
<WorldList v-if="mapCount > 1" v-show="mapsVisible"></WorldList> <WorldsSection v-if="mapCount > 1" v-show="mapsVisible"></WorldsSection>
<PlayerList id="players" v-if="playerMakersEnabled && previouslyVisible.has('players')" <PlayersSection id="players" v-if="playerMakersEnabled && previouslyVisible.has('players')"
v-show="playersVisible"></PlayerList> v-show="playersVisible"></PlayersSection>
<FollowTarget v-if="following" v-show="followVisible" :target="following"></FollowTarget> <FollowTargetSection v-if="following" v-show="followVisible" :target="following"></FollowTargetSection>
</div> </div>
</section> </section>
</template> </template>
<script lang="ts"> <script lang="ts">
import {computed, defineComponent} from "@vue/runtime-core"; import {computed, defineComponent} from "@vue/runtime-core";
import PlayerList from './sidebar/PlayerList.vue'; import FollowTargetSection from './sidebar/FollowTargetSection.vue';
import WorldList from './sidebar/WorldList.vue'; import PlayersSection from "@/components/sidebar/PlayersSection.vue";
import ServerList from "@/components/sidebar/ServerList.vue"; import ServersSection from "@/components/sidebar/ServersSection.vue";
import FollowTarget from './sidebar/FollowTarget.vue'; import WorldsSection from "@/components/sidebar/WorldsSection.vue";
import {useStore} from "@/store"; import {useStore} from "@/store";
import SvgIcon from "@/components/SvgIcon.vue"; import SvgIcon from "@/components/SvgIcon.vue";
import {MutationTypes} from "@/store/mutation-types"; import {MutationTypes} from "@/store/mutation-types";
@ -57,11 +57,11 @@ import {focus} from "@/util";
export default defineComponent({ export default defineComponent({
components: { components: {
ServerList, WorldsSection,
ServersSection,
PlayersSection,
FollowTargetSection,
SvgIcon, SvgIcon,
PlayerList,
FollowTarget,
WorldList,
}, },
setup() { setup() {

View File

@ -0,0 +1,41 @@
<!--
- Copyright 2022 James Lyne
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<template>
<RadioList v-if="players.length">
<PlayerListItem v-for="player in players" :key="player.name" :player="player"></PlayerListItem>
</RadioList>
</template>
<script lang="ts">
import PlayerListItem from "./PlayerListItem.vue";
import {defineComponent} from "@vue/runtime-core";
import RadioList from "@/components/util/RadioList.vue";
import {LiveAtlasPlayer} from "@/index";
export default defineComponent({
components: {
RadioList,
PlayerListItem
},
props: {
players: {
type: Object as () => LiveAtlasPlayer[],
required: true,
}
}
});
</script>

View File

@ -0,0 +1,43 @@
<!--
- Copyright 2022 James Lyne
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<template>
<RadioList aria-labelledby="servers-heading">
<ServerListItem :server="server" v-for="[name, server] in servers" :key="name"></ServerListItem>
</RadioList>
</template>
<script lang="ts">
import ServerListItem from './ServerListItem.vue';
import {defineComponent} from 'vue';
import RadioList from "@/components/util/RadioList.vue";
import {LiveAtlasServerDefinition} from "@/index";
export default defineComponent({
name: 'ServerList',
components: {
RadioList,
ServerListItem
},
props: {
servers: {
type: Object as () => Map<string, LiveAtlasServerDefinition>,
required: true
}
}
});
</script>

View File

@ -0,0 +1,58 @@
<!--
- Copyright 2022 James Lyne
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<template>
<RadioList v-if="worlds.size" aria-labelledby="maps-heading">
<WorldListItem :world="world" v-for="[name, world] in worlds" :key="`${prefix}_${currentServer}_${name}`"></WorldListItem>
</RadioList>
</template>
<script lang="ts">
import WorldListItem from './WorldListItem.vue';
import {defineComponent} from 'vue';
import RadioList from "@/components/util/RadioList.vue";
import {LiveAtlasWorldDefinition} from "@/index";
import {useStore} from "@/store";
import {computed} from "@vue/runtime-core";
export default defineComponent({
name: 'WorldList',
components: {
RadioList,
WorldListItem
},
props: {
prefix: {
type: String,
default: 'map',
},
worlds: {
type: Object as () => Map<string, LiveAtlasWorldDefinition>,
required: true,
}
},
setup() {
const store = useStore(),
currentServer = computed(() => store.state.currentServer ? store.state.currentServer.id : undefined);
return {
currentServer
}
}
});
</script>

View File

@ -45,7 +45,7 @@ import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
import {computed, defineComponent, onMounted, onUnmounted, watch} from "@vue/runtime-core"; import {computed, defineComponent, onMounted, onUnmounted, watch} from "@vue/runtime-core";
import {LeafletMouseEvent} from "leaflet"; import {LeafletMouseEvent} from "leaflet";
import {useStore} from "@/store"; import {useStore} from "@/store";
import WorldListItem from "@/components/sidebar/WorldListItem.vue"; import WorldListItem from "@/components/list/WorldListItem.vue";
import {CSSProperties, ref} from "vue"; import {CSSProperties, ref} from "vue";
import {clipboardError, clipboardSuccess, getUrlForLocation} from "@/util"; import {clipboardError, clipboardSuccess, getUrlForLocation} from "@/util";
import {nextTick} from 'vue'; import {nextTick} from 'vue';

View File

@ -44,7 +44,7 @@ import SvgIcon from "@/components/SvgIcon.vue";
import "@/assets/icons/cross.svg"; import "@/assets/icons/cross.svg";
export default defineComponent({ export default defineComponent({
name: 'FollowTarget', name: 'FollowTargetSection',
components: {SvgIcon}, components: {SvgIcon},
props: { props: {
target: { target: {

View File

@ -1,5 +1,5 @@
<!-- <!--
- Copyright 2021 James Lyne - Copyright 2022 James Lyne
- -
- Licensed under the Apache License, Version 2.0 (the "License"); - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - you may not use this file except in compliance with the License.
@ -20,10 +20,7 @@
<template v-slot:default> <template v-slot:default>
<input v-if="players && searchEnabled" id="players__search" type="text" name="search" <input v-if="players && searchEnabled" id="players__search" type="text" name="search"
v-model="searchQuery" :placeholder="messagePlayersSearchPlaceholder" @keydown="onKeydown"> v-model="searchQuery" :placeholder="messagePlayersSearchPlaceholder" @keydown="onKeydown">
<RadioList v-if="filteredPlayers.length" aria-labelledby="players-heading"> <PlayerList v-if="filteredPlayers.length" :players="filteredPlayers" aria-labelledby="players-heading"></PlayerList>
<PlayerListItem v-for="player in filteredPlayers" :key="player.name"
:player="player"></PlayerListItem>
</RadioList>
<div v-else-if="searchQuery" class="section__skeleton">{{ messageSkeletonPlayersSearch }}</div> <div v-else-if="searchQuery" class="section__skeleton">{{ messageSkeletonPlayersSearch }}</div>
<div v-else class="section__skeleton">{{ messageSkeletonPlayers }}</div> <div v-else class="section__skeleton">{{ messageSkeletonPlayers }}</div>
</template> </template>
@ -31,18 +28,16 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import PlayerListItem from "./PlayerListItem.vue";
import {computed, defineComponent} from "@vue/runtime-core"; import {computed, defineComponent} from "@vue/runtime-core";
import {useStore} from "@/store"; import {useStore} from "@/store";
import RadioList from "@/components/util/RadioList.vue";
import {ref} from "vue"; import {ref} from "vue";
import SidebarSection from "@/components/sidebar/SidebarSection.vue"; import SidebarSection from "@/components/sidebar/SidebarSection.vue";
import PlayerList from "@/components/list/PlayerList.vue";
export default defineComponent({ export default defineComponent({
components: { components: {
PlayerList,
SidebarSection, SidebarSection,
RadioList,
PlayerListItem
}, },
setup() { setup() {

View File

@ -1,5 +1,5 @@
<!-- <!--
- Copyright 2021 James Lyne - Copyright 2022 James Lyne
- -
- Licensed under the Apache License, Version 2.0 (the "License"); - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - you may not use this file except in compliance with the License.
@ -18,26 +18,22 @@
<SidebarSection v-if="servers.size > 1" name="servers"> <SidebarSection v-if="servers.size > 1" name="servers">
<template v-slot:heading>{{ heading }}</template> <template v-slot:heading>{{ heading }}</template>
<template v-slot:default> <template v-slot:default>
<RadioList aria-labelledby="servers-heading"> <ServerList :servers="servers" aria-labelledby="servers-heading"></ServerList>
<ServerListItem :server="server" v-for="[name, server] in servers" :key="name"></ServerListItem>
</RadioList>
</template> </template>
</SidebarSection> </SidebarSection>
</template> </template>
<script lang="ts"> <script lang="ts">
import ServerListItem from './ServerListItem.vue';
import {computed, defineComponent} from 'vue'; import {computed, defineComponent} from 'vue';
import {useStore} from "@/store"; import {useStore} from "@/store";
import SidebarSection from "@/components/sidebar/SidebarSection.vue"; import SidebarSection from "@/components/sidebar/SidebarSection.vue";
import RadioList from "@/components/util/RadioList.vue"; import ServerList from "@/components/list/ServerList.vue";
export default defineComponent({ export default defineComponent({
name: 'ServerList', name: 'ServersSection',
components: { components: {
RadioList, ServerList,
SidebarSection, SidebarSection,
ServerListItem
}, },
setup() { setup() {

View File

@ -27,7 +27,7 @@
<span> <span>
<slot name="heading"></slot> <slot name="heading"></slot>
</span> </span>
<SvgIcon name="arrow"></SvgIcon> <SvgIcon v-if="collapsible" name="arrow"></SvgIcon>
</button> </button>
</h2> </h2>
<div :id="`${name}-content`" class="section__content" :aria-hidden="collapsed"> <div :id="`${name}-content`" class="section__content" :aria-hidden="collapsed">

View File

@ -1,5 +1,5 @@
<!-- <!--
- Copyright 2021 James Lyne - Copyright 2022 James Lyne
- -
- Licensed under the Apache License, Version 2.0 (the "License"); - Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License. - you may not use this file except in compliance with the License.
@ -18,27 +18,23 @@
<SidebarSection name="maps"> <SidebarSection name="maps">
<template v-slot:heading>{{ heading }}</template> <template v-slot:heading>{{ heading }}</template>
<template v-slot:default> <template v-slot:default>
<RadioList v-if="worlds.size" aria-labelledby="maps-heading"> <WorldList v-if="worlds.size" :worlds="worlds" :prefix="prefix" aria-labelledby="maps-heading"></WorldList>
<WorldListItem :world="world" v-for="[name, world] in worlds" :key="`${prefix}_${currentServer}_${name}`"></WorldListItem>
</RadioList>
<div v-else class="section__skeleton">{{ skeleton }}</div> <div v-else class="section__skeleton">{{ skeleton }}</div>
</template> </template>
</SidebarSection> </SidebarSection>
</template> </template>
<script lang="ts"> <script lang="ts">
import WorldListItem from './WorldListItem.vue';
import {computed, defineComponent} from 'vue'; import {computed, defineComponent} from 'vue';
import {useStore} from "@/store"; import {useStore} from "@/store";
import RadioList from "@/components/util/RadioList.vue";
import SidebarSection from "@/components/sidebar/SidebarSection.vue"; import SidebarSection from "@/components/sidebar/SidebarSection.vue";
import WorldList from "@/components/list/WorldList.vue";
export default defineComponent({ export default defineComponent({
name: 'WorldList', name: 'WorldsSection',
components: { components: {
WorldList,
SidebarSection, SidebarSection,
RadioList,
WorldListItem
}, },
props: { props: {