Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add TypeScript with Composition API demo #211

Merged
merged 3 commits into from
Feb 14, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions getting-started-typescript-composition-api/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
24 changes: 24 additions & 0 deletions getting-started-typescript-composition-api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# getting-started-app-typescript

## Project setup
```
npm install
```

### Compiles and hot-reloads for development
```
npm run serve
```

### Compiles and minifies for production
```
npm run build
```

### Lints and fixes files
```
npm run lint
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
5 changes: 5 additions & 0 deletions getting-started-typescript-composition-api/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
59 changes: 59 additions & 0 deletions getting-started-typescript-composition-api/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"name": "getting-started-app-typescript",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@progress/kendo-data-query": "^1.5.5",
"@progress/kendo-drawing": "^1.16.2",
"@progress/kendo-licensing": "^1.2.2",
"@progress/kendo-theme-default": "^5.1.1",
"@progress/kendo-vue-data-tools": "^3.0.5",
"@progress/kendo-vue-dateinputs": "^3.0.5",
"@progress/kendo-vue-dialogs": "^3.0.5",
"@progress/kendo-vue-dropdowns": "^3.0.5",
"@progress/kendo-vue-grid": "^3.0.5",
"@progress/kendo-vue-inputs": "^3.0.5",
"@progress/kendo-vue-intl": "^3.0.5",
"core-js": "^3.6.5",
"vue": "^3.0.0"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-typescript": "^4.5.15",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^7.0.0",
"typescript": "~4.1.5"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript"
],
"parserOptions": {
"parser": "@typescript-eslint/parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
Binary file not shown.
17 changes: 17 additions & 0 deletions getting-started-typescript-composition-api/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
180 changes: 180 additions & 0 deletions getting-started-typescript-composition-api/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<template>
<div id="app">
<h1>Hello Kendo UI for Vue!</h1>
<p>
<dropdownlist
:data-items="categories"
:data-item-key="'CategoryID'"
:text-field="'CategoryName'"
:default-item="defaultItems"
@change="handleDropDownChange"
@rowclick="rowClick"
></dropdownlist>&nbsp; Selected category ID:
<strong>{{ dropdownlistCategory }}</strong>
</p>

<grid
:data-items="dataResult"
:pageable="pageable"
:sortable="sortable"
:sort="sort"
:take="take"
:skip="skip"
:columns="columns"
@datastatechange="dataStateChange"
@rowclick="rowClick"
:style="{ height: '400px' }"
>
<template v-slot:discontinuedTemplate="{ props }">
<td :colspan="1">
<input type="checkbox" :checked="props.dataItem.Discontinued" disabled="disabled" />
</td>
</template>
</grid>

<window v-if="windowVisible" :title="'Product Details'" @close="closeWindow" :height="250">
<dl :style="{ 'text-align': 'left' }">
<dt>Product Name</dt>
<dd>{{ gridClickedRow.ProductName }}</dd>
<dt>Product ID</dt>
<dd>{{ gridClickedRow.ProductID }}</dd>
<dt>Quantity per Unit</dt>
<dd>{{ gridClickedRow.QuantityPerUnit }}</dd>
</dl>
</window>
</div>
</template>

<script lang="ts">
import { ref, onMounted, defineComponent } from 'vue';
import { productsData } from './appdata/products';
import { categoriesData } from './appdata/categories';
import { process, DataResult, State, CompositeFilterDescriptor, SortDescriptor } from '@progress/kendo-data-query';
import { Grid, GridDataStateChangeEvent, GridRowClickEvent, GridColumnProps } from '@progress/kendo-vue-grid';
import { DropDownList, DropDownListChangeEvent } from '@progress/kendo-vue-dropdowns';
import { Window } from '@progress/kendo-vue-dialogs';
import '@progress/kendo-theme-default/dist/all.css';

export default defineComponent({
components: {
dropdownlist: DropDownList,
grid: Grid,
window: Window
},
setup() {
onMounted(() => {
const dataState: State = {
skip: skip.value,
take: take.value,
sort: sort.value,
};
dataResult.value = process(products, dataState);
});

const categories = categoriesData;
const products = productsData;
const defaultItems = { CategoryID: null, CategoryName: "Product categories" };
const dropdownlistCategory = ref(null);
const pageable = ref(true);
const sortable = ref(true);
const skip = ref<number | undefined>(0);
const take = ref<number | undefined>(10);
const sort = ref<SortDescriptor[] | undefined>([
{ field: "ProductName", dir: "asc" }
]);

const filter = ref<CompositeFilterDescriptor>({logic: "and", filters: []});


const columns = [
{ field: 'ProductName', title: 'Product Name' },
{ field: 'UnitPrice', title: 'Price' },
{ field: 'UnitsInStock', title: 'Units in Stock' },
{ field: 'Discontinued', cell: 'discontinuedTemplate' }
] as GridColumnProps[];

const dataResult = ref<DataResult>({ data: [] as any, total: 0 });
const gridClickedRow = ref({});
const windowVisible = ref(false);

const handleDropDownChange = (e: DropDownListChangeEvent) => {
dropdownlistCategory.value = e.target.value.CategoryID;
if (e.target.value.CategoryID !== null) {
filter.value = {
logic: 'and',
filters: [{ field: 'CategoryID', operator: 'eq', value: e.target.value.CategoryID }]
}
skip.value = 0
} else {
filter.value = {} as CompositeFilterDescriptor
skip.value = 0
};

const event: GridDataStateChangeEvent = {
data: {
skip: skip.value,
take: take.value,
sort: sort.value,
filter: filter.value
}
};
dataStateChange(event);
};

const createAppState = (dataState: State) => {
take.value = dataState.take;
skip.value = dataState.skip;
sort.value = dataState.sort;
};

const dataStateChange = (event: GridDataStateChangeEvent) => {
createAppState(event.data);
if (event.data.filter !== undefined && event.data.filter.logic) {
dataResult.value = process(products, {
skip: event.data.skip,
take: event.data.take,
sort: event.data.sort,
filter: event.data.filter
});
} else {
dataResult.value = process(products, {
skip: event.data.skip,
take: event.data.take,
sort: event.data.sort,
});
}
};

const rowClick = (event: GridRowClickEvent) => {
windowVisible.value = true;
gridClickedRow.value = event.dataItem;
};

const closeWindow = () => {
windowVisible.value = false;
}

return {
dropdownlistCategory, categories, defaultItems,
pageable, sortable, dataResult, columns,
sort, take, skip, gridClickedRow, windowVisible,
dataStateChange, handleDropDownChange, rowClick, closeWindow,
}
}

})
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: left;
color: #2c3e50;
margin-top: 60px;
}
dt {
font-weight: bold;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const categories = [
{ "CategoryID": 1, "CategoryName": "Beverages" },
{ "CategoryID": 2, "CategoryName": "Condiments" },
{ "CategoryID": 3, "CategoryName": "Confections" },
{ "CategoryID": 4, "CategoryName": "Dairy Products" },
{ "CategoryID": 5, "CategoryName": "Grains/Cereals" },
{ "CategoryID": 6, "CategoryName": "Meat/Poultry" },
{ "CategoryID": 7, "CategoryName": "Produce" },
{ "CategoryID": 8, "CategoryName": "Seafood" }
];

export { categories as categoriesData }
20 changes: 20 additions & 0 deletions getting-started-typescript-composition-api/src/appdata/products.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const products = [
{ "ProductID": 1, "ProductName": "Tea", "CategoryID": 1, "QuantityPerUnit": "10 boxes x 20 bags", "UnitPrice": 18.0, "UnitsInStock": 39, "Discontinued": false },
{ "ProductID": 7, "ProductName": "Dried Pears", "CategoryID": 7, "QuantityPerUnit": "12 - 1 lb pkgs.", "UnitPrice": 30.0, "UnitsInStock": 15, "Discontinued": false },
{ "ProductID": 8, "ProductName": "Cranberry Sauce", "CategoryID": 2, "QuantityPerUnit": "12 - 12 oz jars", "UnitPrice": 40.0, "UnitsInStock": 6, "Discontinued": false },
{ "ProductID": 9, "ProductName": "Mishi Kobe Niku", "CategoryID": 6, "QuantityPerUnit": "18 - 500 g pkgs.", "UnitPrice": 97.0, "UnitsInStock": 29, "Discontinued": true },
{ "ProductID": 14, "ProductName": "Tofu", "CategoryID": 7, "QuantityPerUnit": "40 - 100 g pkgs.", "UnitPrice": 23.25, "UnitsInStock": 35, "Discontinued": false },
{ "ProductID": 17, "ProductName": "Alice Mutton", "CategoryID": 6, "QuantityPerUnit": "20 - 1 kg tins", "UnitPrice": 39.0, "UnitsInStock": 0, "Discontinued": false },
{ "ProductID": 19, "ProductName": "Teatime Biscuits", "CategoryID": 3, "QuantityPerUnit": "10 boxes x 12 pieces", "UnitPrice": 9.2, "UnitsInStock": 25, "Discontinued": false },
{ "ProductID": 40, "ProductName": "Boston Crab Meat", "CategoryID": 8, "QuantityPerUnit": "24 - 4 oz tins", "UnitPrice": 18.4, "UnitsInStock": 123, "Discontinued": false },
{ "ProductID": 43, "ProductName": "Coffee", "CategoryID": 1, "QuantityPerUnit": "16 - 500 g tins", "UnitPrice": 46.0, "UnitsInStock": 17, "Discontinued": false },
{ "ProductID": 48, "ProductName": "Chocolate", "CategoryID": 3, "QuantityPerUnit": "10 pkgs.", "UnitPrice": 12.75, "UnitsInStock": 15, "Discontinued": false },
{ "ProductID": 56, "ProductName": "Gnocchi di nonna Alice", "CategoryID": 5, "QuantityPerUnit": "24 - 250 g pkgs.", "UnitPrice": 38.0, "UnitsInStock": 21, "Discontinued": true },
{ "ProductID": 57, "ProductName": "Ravioli Angelo", "CategoryID": 5, "QuantityPerUnit": "24 - 250 g pkgs.", "UnitPrice": 19.5, "UnitsInStock": 36, "Discontinued": false },
{ "ProductID": 60, "ProductName": "Camembert Pierrot", "CategoryID": 4, "QuantityPerUnit": "15 - 300 g rounds", "UnitPrice": 34.0, "UnitsInStock": 19, "Discontinued": true },
{ "ProductID": 65, "ProductName": "Hot Pepper Sauce", "CategoryID": 2, "QuantityPerUnit": "32 - 8 oz bottles", "UnitPrice": 21.05, "UnitsInStock": 76, "Discontinued": false },
{ "ProductID": 72, "ProductName": "Mozzarella di Giovanni", "CategoryID": 4, "QuantityPerUnit": "24 - 200 g pkgs.", "UnitPrice": 34.8, "UnitsInStock": 14, "Discontinued": false },
{ "ProductID": 73, "ProductName": "Röd Kaviar", "CategoryID": 8, "QuantityPerUnit": "24 - 150 g jars", "UnitPrice": 15.0, "UnitsInStock": 101, "Discontinued": true }
];

export { products as productsData };
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions getting-started-typescript-composition-api/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')
6 changes: 6 additions & 0 deletions getting-started-typescript-composition-api/src/shims-vue.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
Loading