-
Notifications
You must be signed in to change notification settings - Fork 4
/
NetflixTable.vue
122 lines (112 loc) · 3.5 KB
/
NetflixTable.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<script setup lang="ts">
/**
* This component implements a-tables for fast data demo.
* It uses tags and tooltips to provide essential UI components for many VA systems.
*/
import { ref, onMounted } from 'vue';
import type { TableColumnsType } from 'ant-design-vue';
import { useConfig } from '../stores/vaConfig';
import { useNetflixStore, type Show } from '../stores/netflix';
import { useStaticNetflixStore } from '../stores/netflixStatic';
import { storeToRefs } from 'pinia';
const vaConfig = useConfig(); // define colors
const netflixStore = vaConfig.hasServer
? useNetflixStore()
: useStaticNetflixStore(); // define data source according to the environment
const { billBurr } = storeToRefs(netflixStore); // obtain reactive variables
const tableScrollHeight = ref<number>(240); // 300 total height - 60 from header
// define the table columns
const columns: TableColumnsType = [
{ title: 'Title', dataIndex: 'title', key: 'title' },
{
title: 'Year',
dataIndex: 'release_year',
key: 'release_year',
defaultSortOrder: 'descend',
sorter: (a: Show, b: Show) => a.release_year - b.release_year, // define sorting order
},
{ title: 'Country', dataIndex: 'country', key: 'country' },
{ title: 'Genre', dataIndex: 'listed_in', key: 'genre' },
];
// list the color used for each genre
const genreColor = (tag: string): string => {
tag = tag.toLowerCase();
return tag.includes('comed')
? vaConfig.color.type_one
: tag.includes('movie')
? vaConfig.color.type_two
: vaConfig.color.type_three;
};
// list the flag used for each country
const countryTag = (tag: string): string => {
switch (tag) {
case 'United States':
tag = 'US';
break;
case 'United Kingdom':
tag = 'GB';
break;
case 'Canada':
tag = 'CA';
break;
case 'France':
tag = 'FR';
break;
}
// convert ISO 3166-1 alpha-2 string into country flag emoji
// refer to https://github.com/thekelvinliu/country-code-emoji/blob/main/src/index.js
const OFFSET = 127397;
const codePoints = [...tag].map((c) => (c.codePointAt(0) as number) + OFFSET);
return String.fromCodePoint(...codePoints);
};
// define the tooltip container
const getPopupContainer = (trigger: HTMLElement) => {
return trigger.parentElement;
};
onMounted(() => {
netflixStore.get_bill_burr(); // get the data after the component is mounted
});
</script>
<template>
<div class="netflix noselect">
<a-table
:columns="columns"
:data-source="billBurr"
:scroll="{ y: tableScrollHeight }"
:pagination="false"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'genre'">
<span>
<!-- Show tags in different colors for each genre -->
<a-tag
v-for="tag in record.listed_in.split(', ')"
:key="tag"
:color="genreColor(tag)"
>
{{ tag }}
</a-tag>
</span>
</template>
<template v-else-if="column.key === 'country'">
<span v-for="tag in record.country.split(', ')" :key="tag">
<!-- Show tooltip for hovering over country flag -->
<a-tooltip :title="tag" :get-popup-container="getPopupContainer">
{{ countryTag(tag) }}
</a-tooltip>
</span>
</template>
</template>
</a-table>
</div>
</template>
<style scoped>
.netflix {
height: calc(100% - 2px);
width: 100%;
border: 1px solid black;
}
.noselect {
user-select: none;
}
</style>