Skip to content

Commit

Permalink
♻️ [so] refactor to composition API
Browse files Browse the repository at this point in the history
  • Loading branch information
jxn-30 committed Aug 26, 2023
1 parent 9fba72d commit a245f81
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 490 deletions.
1 change: 1 addition & 0 deletions src/components/EnhancedTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<button
class="btn btn-default toggle-head-btn"
:class="{ hidden: !scrolledOver }"
@click.prevent="showHead = !showHead"
>
<font-awesome-icon :icon="faSlidersH"></font-awesome-icon>
</button>
Expand Down
4 changes: 2 additions & 2 deletions src/modules/redesign/components/schoolings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ export default Vue.extend<
),
OwnSchoolingTabs: () =>
import(
/*webpackChunkName: "modules/schoolingOverview/ownSchoolingTabs"*/ '../../schoolingOverview/components/ownSchoolingTabs.vue'
/*webpackChunkName: "modules/schoolingOverview/ownSchoolingTabs"*/ '../../schoolingOverview/components/OwnSchoolingTabs.vue'
),
OpenSchoolingTabs: () =>
import(
/*webpackChunkName: "modules/schoolingOverview/openSchoolingTabs"*/ '../../schoolingOverview/components/openSchoolingTabs.vue'
/*webpackChunkName: "modules/schoolingOverview/openSchoolingTabs"*/ '../../schoolingOverview/components/OpenSchoolingTabs.vue'
),
},
data() {
Expand Down
40 changes: 40 additions & 0 deletions src/modules/schoolingOverview/components/OpenSchoolingTabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<SchoolingTabs
:title="title"
collapsed-setting="hide_openschooling"
:columns="['name', 'seats', 'price', 'end', 'owner']"
:tabs="tabs"
>
<template v-slot="{ schooling, countdownId }">
<td>
<a
class="btn btn-success"
:href="`/schoolings/${schooling.id}`"
>
{{ schooling.name }}
</a>
</td>
<td>{{ schooling.seats }}</td>
<td>{{ schooling.price }}</td>
<td :id="countdownId(schooling)">
{{ schooling.end }}
</td>
<td v-html="schooling.owner"></td>
</template>
</SchoolingTabs>
</template>

<script setup lang="ts">
import SchoolingTabs from './SchoolingTabs.vue';
import { useI18nModule } from '../../../i18n';
import type { OpenSchoolings } from 'typings/modules/SchoolingOverview/main';
const { $m } = useI18nModule('schoolingOverview');
const title = $m('open').toString();
defineProps<{
tabs: OpenSchoolings['tabs'];
}>();
</script>
38 changes: 38 additions & 0 deletions src/modules/schoolingOverview/components/OwnSchoolingTabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<SchoolingTabs
:title="title"
collapsed-setting="hide_ownschooling"
:columns="['name', 'end', 'owner']"
:tabs="tabs"
>
<template v-slot="{ schooling, countdownId }">
<td>
<a
class="btn btn-success"
:href="`/schoolings/${schooling.id}`"
>
{{ schooling.name }}
</a>
</td>
<td :id="countdownId(schooling)">
{{ schooling.end }}
</td>
<td v-html="schooling.owner"></td>
</template>
</SchoolingTabs>
</template>

<script setup lang="ts">
import SchoolingTabs from './SchoolingTabs.vue';
import { useI18nModule } from '../../../i18n';
import type { OwnSchoolings } from 'typings/modules/SchoolingOverview/main';
const { $m } = useI18nModule('schoolingOverview');
const title = $m('own').toString();
defineProps<{
tabs: OwnSchoolings['tabs'];
}>();
</script>
157 changes: 157 additions & 0 deletions src/modules/schoolingOverview/components/SchoolingTabs.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<template>
<div>
<div class="title-wrapper">
<h3>
{{ title }}
<button
class="btn btn-xs collapse-button"
:class="`btn-${collapsed ? 'success' : 'danger'}`"
@click="toggleCollapsed"
>
<font-awesome-icon
:icon="collapsed ? faExpandAlt : faCompressAlt"
/>
</button>
</h3>
</div>
<tabs :on-select="setTab" v-show="!collapsed">
<tab v-for="tab in tabTitles" :key="tab" :title="tab">
<enhanced-table
:columns="cols"
:column-translations="$cols"
:table-attrs="{ class: 'table table-striped' }"
@sort="setSorting"
:sort="sort"
:sort-dir="sortDir"
:search="search"
@search="s => (search = s)"
@hook:mounted="initCountdowns"
>
<tr
v-for="(schooling, id) in schoolings"
:key="id"
class="schooling_opened_table_searchable"
>
<slot v-bind="{ schooling, countdownId }"></slot>
</tr>
</enhanced-table>
</tab>
</tabs>
</div>
</template>

<script setup lang="ts">
import { computed, nextTick, onBeforeMount, onMounted, ref } from 'vue';
import { faCompressAlt } from '@fortawesome/free-solid-svg-icons/faCompressAlt';
import { faExpandAlt } from '@fortawesome/free-solid-svg-icons/faExpandAlt';
import { useRootStore } from '@stores/index';
import { useSettingsStore } from '@stores/settings';
import EnhancedTable from '../../../components/EnhancedTable.vue';
import { useI18nModule } from '../../../i18n';
import type {
OpenSchoolings,
OwnSchoolings,
} from 'typings/modules/SchoolingOverview/main';
const { $m, $t } = useI18nModule('schoolingOverview');
const all = $m('all').toString();
const rootStore = useRootStore();
const settingsStore = useSettingsStore();
const uuid = crypto.randomUUID();
const collapsed = ref<boolean>(false);
const search = ref<string>('');
const sort = ref<string>('');
const sortDir = ref<'asc' | 'desc'>('asc');
const currentTab = ref<string>(all);
const props = defineProps<{
title: string;
columns: string[];
tabs: OpenSchoolings['tabs'] | OwnSchoolings['tabs'];
collapsedSetting: 'hide_openschooling' | 'hide_ownschooling';
}>();
const cols = computed(() => props.columns.map(key => ({ key })));
const $cols = computed(() => $m('titles') as Record<string, string>);
const tabTitles = computed(() => [all, ...Object.keys($t('schoolings'))]);
const schoolings = computed(() => {
const schoolings = props.tabs[currentTab.value] || [];
return (
search.value
? schoolings.filter(a =>
JSON.stringify(Object.values(a))
.toLowerCase()
.match(search.value.toLowerCase())
)
: schoolings
).toSorted((a, b) => {
let modifier = 1;
if (sortDir.value === 'desc') modifier = -1;
if (a[sort.value] < b[sort.value]) return -1 * modifier;
if (a[sort.value] > b[sort.value]) return modifier;
return 0;
});
});
const toggleCollapsed = () => {
collapsed.value = !collapsed.value;
settingsStore.setSetting({
moduleId: 'schoolingOverview',
settingId: props.collapsedSetting,
value: collapsed.value,
});
};
const setTab = (_, index: number) => {
currentTab.value = tabTitles.value[index] || all;
initCountdowns();
};
const setSorting = (key: string) => {
sortDir.value =
key === sort.value && sortDir.value === 'asc' ? 'desc' : 'asc';
sort.value = key;
};
const countdownId = (schooling: { id: number }) =>
rootStore.nodeAttribute(
`schoolingOverview_countdown_${schooling.id}-${uuid}`,
true
);
const initCountdowns = () =>
schoolings.value.forEach(schooling =>
window[PREFIX].$utils.countdown(countdownId(schooling), schooling.end)
);
onBeforeMount(() => {
if (props.columns.length && !sort.value) sort.value = props.columns[0];
settingsStore
.getSetting<boolean>({
moduleId: 'schoolingOverview',
settingId: props.collapsedSetting,
})
.then(isCollapsed => (collapsed.value = isCollapsed));
});
onMounted(() => nextTick(initCountdowns));
</script>

<style scoped lang="sass">
th
cursor: pointer
.title-wrapper
display: flex
margin-bottom: 1rem
.collapse-button
margin-left: 1rem
</style>
Loading

0 comments on commit a245f81

Please sign in to comment.