Backend API
<template>
<DxDataGrid
id="grid-container"
:show-borders="true"
:data-source="employees"
key-expr="ID"
>
<DxColumn
:width="70"
data-field="Prefix"
caption="Title"
/>
<DxColumn data-field="FirstName"/>
<DxColumn data-field="LastName"/>
<DxColumn
:width="170"
data-field="Position"
/>
<DxColumn
:width="125"
data-field="State"
/>
<DxColumn
data-field="BirthDate"
data-type="date"
/>
<DxMasterDetail
:enabled="true"
template="masterDetailTemplate"
/>
<template #masterDetailTemplate="{ data: employee }">
<DetailTemplate
:template-data="employee"
/>
</template>
</DxDataGrid>
</template>
<script setup lang="ts">
import {
DxDataGrid,
DxColumn,
DxMasterDetail,
} from 'devextreme-vue/data-grid';
import DetailTemplate from './DetailTemplate.vue';
import { employees } from './data.ts';
</script>
<style>
#grid-container {
height: 440px;
}
</style>
<template>
<div>
<div class="master-detail-caption">{{ detailInfo }}</div>
<DxDataGrid
:data-source="dataSource"
:show-borders="true"
:column-auto-width="true"
>
<DxColumn data-field="Subject"/>
<DxColumn
data-field="StartDate"
data-type="date"
/>
<DxColumn
data-field="DueDate"
data-type="date"
/>
<DxColumn data-field="Priority"/>
<DxColumn
:calculate-cell-value="completedValue"
data-type="boolean"
caption="Completed"
/>
</DxDataGrid>
</div>
</template>
<script setup lang="ts">
import { reactive } from 'vue';
import { DxDataGrid, DxColumn, type DxDataGridTypes } from 'devextreme-vue/data-grid';
import { ArrayStore, DataSource } from 'devextreme-vue/common/data';
import { tasks, type Task } from './data.ts';
const props = defineProps<{
templateData: DxDataGridTypes.MasterDetailTemplateData
}>();
const dataSource = getTasks(props.templateData.key);
const itemData = reactive(props.templateData.data);
const detailInfo = `${itemData.FirstName} ${itemData.LastName}'s Tasks:`;
const completedValue = (rowData: Task) => rowData.Status === 'Completed';
function getTasks(key: number) {
return new DataSource({
store: new ArrayStore({
data: tasks,
key: 'ID',
}),
filter: ['EmployeeID', '=', key],
});
}
</script>
<style>
.master-detail-caption {
padding: 0 0 5px 10px;
font-size: 14px;
font-weight: bold;
}
</style>
export type Task = {
ID: number;
Subject: string;
StartDate: string;
DueDate: string;
Status: string;
Priority: string;
Completion: number;
EmployeeID: number;
};
export type Employee = {
ID: number;
FirstName: string;
LastName: string;
Prefix: string;
Position: string;
BirthDate: string;
State: string;
};
export const employees: Employee[] = [{
ID: 1,
Prefix: 'Mr.',
FirstName: 'John',
LastName: 'Heart',
Position: 'CEO',
State: 'California',
BirthDate: '1964/03/16',
},
{
ID: 2,
Prefix: 'Mrs.',
FirstName: 'Olivia',
LastName: 'Peyton',
Position: 'Sales Assistant',
State: 'California',
BirthDate: '1981/06/03',
},
{
ID: 3,
Prefix: 'Mr.',
FirstName: 'Robert',
LastName: 'Reagan',
Position: 'CMO',
State: 'Arkansas',
BirthDate: '1974/09/07',
},
{
ID: 4,
Prefix: 'Ms.',
FirstName: 'Greta',
LastName: 'Sims',
Position: 'HR Manager',
State: 'Georgia',
BirthDate: '1977/11/22',
},
{
ID: 5,
Prefix: 'Mr.',
FirstName: 'Brett',
LastName: 'Wade',
Position: 'IT Manager',
State: 'Idaho',
BirthDate: '1968/12/01',
},
{
ID: 6,
Prefix: 'Mrs.',
FirstName: 'Sandra',
LastName: 'Johnson',
Position: 'Controller',
State: 'Utah',
BirthDate: '1974/11/15',
},
{
ID: 7,
Prefix: 'Mr.',
FirstName: 'Kevin',
LastName: 'Carter',
Position: 'Shipping Manager',
State: 'California',
BirthDate: '1978/01/09',
},
{
ID: 8,
Prefix: 'Ms.',
FirstName: 'Cynthia',
LastName: 'Stanwick',
Position: 'HR Assistant',
State: 'Arkansas',
BirthDate: '1985/06/05',
},
{
ID: 9,
Prefix: 'Dr.',
FirstName: 'Kent',
LastName: 'Samuelson',
Position: 'Ombudsman',
State: 'Missouri',
BirthDate: '1972/09/11',
}];
export const tasks: Task[] = [{
ID: 1,
Subject: 'Prepare 2023 Financial',
StartDate: '2023/01/15',
DueDate: '2023/01/31',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 8,
},
{
ID: 2,
Subject: 'Prepare 2023 Marketing Plan',
StartDate: '2023/01/01',
DueDate: '2023/01/31',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 5,
},
{
ID: 3,
Subject: 'Update Personnel Files',
StartDate: '2023/02/03',
DueDate: '2023/02/28',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 2,
},
{
ID: 4,
Subject: 'Review Health Insurance Options Under the Affordable Care Act',
StartDate: '2023/02/12',
DueDate: '2023/04/25',
Status: 'In Progress',
Priority: 'High',
Completion: 50,
EmployeeID: 2,
},
{
ID: 5,
Subject: 'Choose between PPO and HMO Health Plan',
StartDate: '2023/02/15',
DueDate: '2023/04/15',
Status: 'In Progress',
Priority: 'High',
Completion: 75,
EmployeeID: 1,
},
{
ID: 6,
Subject: 'Google AdWords Strategy',
StartDate: '2023/02/16',
DueDate: '2023/02/28',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 1,
},
{
ID: 7,
Subject: 'New Brochures',
StartDate: '2023/02/17',
DueDate: '2023/02/24',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 1,
},
{
ID: 11,
Subject: 'Rollout of New Website and Marketing Brochures',
StartDate: '2023/02/20',
DueDate: '2023/02/28',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 5,
},
{
ID: 12,
Subject: 'Update Sales Strategy Documents',
StartDate: '2023/02/20',
DueDate: '2023/02/22',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 9,
},
{
ID: 15,
Subject: 'Review 2022 Sales Report and Approve 2023 Plans',
StartDate: '2023/02/23',
DueDate: '2023/02/28',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 5,
},
{
ID: 16,
Subject: 'Deliver R&D Plans for 2023',
StartDate: '2023/03/01',
DueDate: '2023/03/10',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 3,
},
{
ID: 20,
Subject: 'Approve Hiring of John Jeffers',
StartDate: '2023/03/02',
DueDate: '2023/03/12',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 4,
},
{
ID: 20,
Subject: 'Approve Hiring of John Jeffers',
StartDate: '2023/03/02',
DueDate: '2023/03/12',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 6,
},
{
ID: 21,
Subject: 'Non-Compete Agreements',
StartDate: '2023/03/12',
DueDate: '2023/03/14',
Status: 'Completed',
Priority: 'Low',
Completion: 100,
EmployeeID: 2,
},
{
ID: 22,
Subject: 'Update NDA Agreement',
StartDate: '2023/03/14',
DueDate: '2023/03/16',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 1,
},
{
ID: 23,
Subject: 'Update Employee Files with New NDA',
StartDate: '2023/03/16',
DueDate: '2023/03/26',
Status: 'Need Assistance',
Priority: 'Normal',
Completion: 90,
EmployeeID: 4,
},
{
ID: 24,
Subject: 'Update Employee Files with New NDA',
StartDate: '2023/03/16',
DueDate: '2023/03/26',
Status: 'Need Assistance',
Priority: 'Normal',
Completion: 90,
EmployeeID: 6,
},
{
ID: 25,
Subject: 'Sign Updated NDA',
StartDate: '2023/03/20',
DueDate: '2023/03/25',
Status: 'Completed',
Priority: 'Urgent',
Completion: 100,
EmployeeID: 7,
},
{
ID: 26,
Subject: 'Sign Updated NDA',
StartDate: '2023/03/20',
DueDate: '2023/03/25',
Status: 'Completed',
Priority: 'Urgent',
Completion: 100,
EmployeeID: 8,
},
{
ID: 27,
Subject: 'Sign Updated NDA',
StartDate: '2023/03/20',
DueDate: '2023/03/25',
Status: 'Need Assistance',
Priority: 'Urgent',
Completion: 25,
EmployeeID: 9,
},
{
ID: 35,
Subject: 'Update Revenue Projections',
StartDate: '2023/03/24',
DueDate: '2023/04/07',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 8,
},
{
ID: 36,
Subject: 'Review Revenue Projections',
StartDate: '2023/03/25',
DueDate: '2023/04/06',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 9,
},
{
ID: 40,
Subject: 'Provide New Health Insurance Docs',
StartDate: '2023/03/28',
DueDate: '2023/04/07',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 4,
},
{
ID: 41,
Subject: 'Provide New Health Insurance Docs',
StartDate: '2023/03/28',
DueDate: '2023/04/07',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 6,
},
{
ID: 50,
Subject: 'Give Final Approval for Refunds',
StartDate: '2023/05/05',
DueDate: '2023/05/15',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 2,
},
{
ID: 52,
Subject: 'Review Product Recall Report by Engineering Team',
StartDate: '2023/05/17',
DueDate: '2023/05/20',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 1,
},
{
ID: 55,
Subject: 'Review Overtime Report',
StartDate: '2023/06/10',
DueDate: '2023/06/14',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 7,
},
{
ID: 60,
Subject: 'Refund Request Template',
StartDate: '2023/06/17',
DueDate: '2024/04/01',
Status: 'Deferred',
Priority: 'Normal',
Completion: 0,
EmployeeID: 9,
},
{
ID: 71,
Subject: 'Upgrade Server Hardware',
StartDate: '2023/07/22',
DueDate: '2023/07/31',
Status: 'Completed',
Priority: 'Urgent',
Completion: 100,
EmployeeID: 7,
},
{
ID: 72,
Subject: 'Upgrade Personal Computers',
StartDate: '2023/07/24',
DueDate: '2024/04/30',
Status: 'In Progress',
Priority: 'Normal',
Completion: 85,
EmployeeID: 7,
},
{
ID: 74,
Subject: 'Decide on Mobile Devices to Use in the Field',
StartDate: '2023/07/30',
DueDate: '2023/08/02',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 3,
},
{
ID: 78,
Subject: 'Try New Touch-Enabled WinForms Apps',
StartDate: '2023/08/11',
DueDate: '2023/08/15',
Status: 'Completed',
Priority: 'Normal',
Completion: 100,
EmployeeID: 3,
},
{
ID: 81,
Subject: 'Review Site Up-Time Report',
StartDate: '2023/08/24',
DueDate: '2023/08/30',
Status: 'Completed',
Priority: 'Urgent',
Completion: 100,
EmployeeID: 5,
},
{
ID: 99,
Subject: 'Submit D&B Number to ISP for Credit Approval',
StartDate: '2023/11/04',
DueDate: '2023/11/07',
Status: 'Completed',
Priority: 'High',
Completion: 100,
EmployeeID: 8,
},
{
ID: 117,
Subject: 'Approval on Converting to New HDMI Specification',
StartDate: '2024/01/11',
DueDate: '2024/01/31',
Status: 'Deferred',
Priority: 'Normal',
Completion: 75,
EmployeeID: 3,
},
{
ID: 138,
Subject: 'Review HR Budget Company Wide',
StartDate: '2024/03/20',
DueDate: '2024/03/25',
Status: 'In Progress',
Priority: 'Normal',
Completion: 40,
EmployeeID: 6,
},
{
ID: 145,
Subject: 'Final Budget Review',
StartDate: '2024/03/26',
DueDate: '2024/03/27',
Status: 'In Progress',
Priority: 'High',
Completion: 25,
EmployeeID: 6,
}];
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
<!DOCTYPE html>
<html lang="en">
<head>
<title>DevExtreme Demo</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" />
<link rel="stylesheet" type="text/css" href="./bundle.css" />
</head>
<body class="dx-viewport">
<div class="demo-container">
<div id="app"> </div>
</div>
<script src="bundles/vendor/vue.vendor.js"></script>
<script src="./bundle.js"></script>
</body>
</html>