Skip to content

Commit d119ac5

Browse files
Vue: Composition API migration with DevExtreme Vue types and kebab-case CSS
- Migrated to Vue 3 Composition API with <script setup lang="ts"> - Updated to DevExtreme Vue types (DxDataGridTypes, DxFileUploaderTypes) - Removed redundant text prop from DxButton, using slot content instead - Updated CSS classes to kebab-case (.retry-button, .uploaded-image) - Removed unused event parameters from handlers - Added proper TypeScript typing for all event handlers - Created constants.ts for backendURL - Updated data.ts with Employee interface - Build and lint passing with 0 errors
1 parent c228fa9 commit d119ac5

File tree

6 files changed

+162
-161
lines changed

6 files changed

+162
-161
lines changed

Vue/package-lock.json

Lines changed: 0 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Vue/src/assets/main.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
-webkit-font-smoothing: antialiased;
44
-moz-osx-font-smoothing: grayscale;
55
color: #2c3e50;
6-
margin: 50px 50px;
7-
width: 90vh;
6+
margin: 50px;
7+
width: 90vw;
88
}

Vue/src/components/HomeContent.vue

Lines changed: 77 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,29 @@
11
<script setup lang="ts">
2-
import { ref, type Ref } from "vue";
2+
import { ref, type Ref } from 'vue';
33
4-
import "devextreme/dist/css/dx.material.blue.light.compact.css";
4+
import 'devextreme/dist/css/dx.material.blue.light.compact.css';
55
66
import DxDataGrid, {
77
DxColumn,
88
DxEditing,
99
DxPopup,
1010
DxForm,
11-
} from "devextreme-vue/data-grid";
12-
import DxFileUploader from "devextreme-vue/file-uploader";
13-
import { DxItem } from "devextreme-vue/form";
14-
import DxButton from "devextreme-vue/button";
15-
16-
import type {
17-
UploadedEvent,
18-
UploadErrorEvent,
19-
ValueChangedEvent,
20-
} from "devextreme/ui/file_uploader";
21-
import type {
22-
ColumnEditCellTemplateData,
23-
EditCanceledEvent,
24-
SavedEvent,
25-
} from "devextreme/ui/data_grid";
26-
import type { ClickEvent } from "devextreme/ui/button";
27-
import { employees, type Employee } from "../data";
28-
import { backendURL } from "../constants";
11+
type DxDataGridTypes,
12+
} from 'devextreme-vue/data-grid';
13+
import DxFileUploader, { type DxFileUploaderTypes } from 'devextreme-vue/file-uploader';
14+
import { DxItem } from 'devextreme-vue/form';
15+
import DxButton from 'devextreme-vue/button';
16+
17+
import { employees, type Employee } from '../data';
18+
import { backendURL } from '../constants';
2919
3020
// Reactive refs
3121
const fileUploaderRef: Ref<InstanceType<typeof DxFileUploader> | null> = ref(null);
3222
const imageRef: Ref<HTMLImageElement | null> = ref(null);
3323
const retryButtonVisible = ref<boolean>(false);
3424
3525
// Event handlers with proper typing
36-
function onClick(_e: ClickEvent): void {
26+
function onClick(): void {
3727
// The retry UI/API is not implemented. Use the private API as shown at T611719.
3828
const fileUploaderInstance = fileUploaderRef.value?.instance;
3929
if (fileUploaderInstance) {
@@ -46,11 +36,11 @@ function onClick(_e: ClickEvent): void {
4636
}
4737
}
4838
49-
function onValueChanged(e: ValueChangedEvent): void {
39+
function onValueChanged(e: DxFileUploaderTypes.ValueChangedEvent): void {
5040
if (e.value && e.value.length > 0) {
5141
const reader = new FileReader();
5242
reader.onload = (args) => {
53-
if (typeof args.target?.result === "string" && imageRef.value) {
43+
if (typeof args.target?.result === 'string' && imageRef.value) {
5444
imageRef.value.src = args.target.result;
5545
}
5646
};
@@ -59,32 +49,34 @@ function onValueChanged(e: ValueChangedEvent): void {
5949
}
6050
6151
// Higher-order function for upload success handler
62-
const createUploadedHandler = (cellInfo: ColumnEditCellTemplateData<Employee, number>) =>
63-
(e: UploadedEvent): void => {
52+
const createUploadedHandler = (
53+
cellInfo: DxDataGridTypes.ColumnEditCellTemplateData<Employee, number>
54+
) =>
55+
(e: DxFileUploaderTypes.UploadedEvent): void => {
6456
if (e.request?.responseText) {
65-
cellInfo.setValue("images/employees/" + e.request.responseText);
57+
cellInfo.setValue(`images/employees/${e.request.responseText}`);
6658
retryButtonVisible.value = false;
6759
}
6860
};
6961
70-
function onUploadError(e: UploadErrorEvent): void {
62+
function onUploadError(e: DxFileUploaderTypes.UploadErrorEvent): void {
7163
const xhttp = e.request;
7264
if (xhttp && xhttp.status === 400) {
73-
e.message = e.error?.responseText || "Upload error";
65+
e.message = e.error?.responseText || 'Upload error';
7466
}
7567
if (xhttp && xhttp.readyState === 4 && xhttp.status === 0) {
76-
e.message = "Connection refused";
68+
e.message = 'Connection refused';
7769
}
7870
retryButtonVisible.value = true;
7971
}
8072
81-
function onEditCanceled(_e: EditCanceledEvent<Employee, number>): void {
73+
function onEditCanceled(): void {
8274
if (retryButtonVisible.value) {
8375
retryButtonVisible.value = false;
8476
}
8577
}
8678
87-
function onSaved(_e: SavedEvent<Employee, number>): void {
79+
function onSaved(): void {
8880
if (retryButtonVisible.value) {
8981
retryButtonVisible.value = false;
9082
}
@@ -101,24 +93,38 @@ function onSaved(_e: SavedEvent<Employee, number>): void {
10193
@saved="onSaved"
10294
@edit-canceled="onEditCanceled"
10395
>
104-
<DxEditing :allow-updating="true" mode="popup">
105-
<DxPopup :show-title="true" :width="700" title="Employee Info" />
96+
<DxEditing
97+
:allow-updating="true"
98+
mode="popup"
99+
>
100+
<DxPopup
101+
:show-title="true"
102+
:width="700"
103+
title="Employee Info"
104+
/>
106105
<DxForm>
107-
<DxItem :col-count="2" :col-span="2" item-type="group">
108-
<DxItem data-field="Prefix" />
109-
<DxItem data-field="FirstName" />
110-
<DxItem data-field="LastName" />
111-
<DxItem data-field="Position" />
112-
<DxItem data-field="BirthDate" />
113-
<DxItem data-field="HireDate" />
106+
<DxItem
107+
:col-count="2"
108+
:col-span="2"
109+
item-type="group"
110+
>
111+
<DxItem data-field="Prefix"/>
112+
<DxItem data-field="FirstName"/>
113+
<DxItem data-field="LastName"/>
114+
<DxItem data-field="Position"/>
115+
<DxItem data-field="BirthDate"/>
116+
<DxItem data-field="HireDate"/>
114117
</DxItem>
115118
<DxItem
116119
:col-count="2"
117120
:col-span="2"
118121
item-type="group"
119122
caption="Photo"
120123
>
121-
<DxItem data-field="Picture" :col-span="2" />
124+
<DxItem
125+
data-field="Picture"
126+
:col-span="2"
127+
/>
122128
</DxItem>
123129
</DxForm>
124130
</DxEditing>
@@ -129,47 +135,58 @@ function onSaved(_e: SavedEvent<Employee, number>): void {
129135
cell-template="cellTemplate"
130136
edit-cell-template="editCellTemplate"
131137
/>
132-
<DxColumn data-field="Prefix" :width="70" caption="Title" />
133-
<DxColumn data-field="FirstName" />
134-
<DxColumn data-field="LastName" />
135-
<DxColumn data-field="Position" />
136-
<DxColumn data-field="BirthDate" data-type="date" />
137-
<DxColumn data-field="HireDate" data-type="date" />
138-
138+
<DxColumn
139+
data-field="Prefix"
140+
:width="70"
141+
caption="Title"
142+
/>
143+
<DxColumn data-field="FirstName"/>
144+
<DxColumn data-field="LastName"/>
145+
<DxColumn data-field="Position"/>
146+
<DxColumn
147+
data-field="BirthDate"
148+
data-type="date"
149+
/>
150+
<DxColumn
151+
data-field="HireDate"
152+
data-type="date"
153+
/>
154+
139155
<!-- Cell template for displaying images -->
140156
<template #cellTemplate="{ data }">
141-
<img
142-
:src="backendURL + data.value"
157+
<img
158+
:src="backendURL + data.value"
143159
alt="employee pic"
144160
style="max-width: 100%; height: auto;"
145-
/>
161+
>
146162
</template>
147-
163+
148164
<!-- Edit cell template for file upload -->
149165
<template #editCellTemplate="{ data }">
150166
<div class="file-uploader-container">
151167
<img
152168
ref="imageRef"
153-
class="uploadedImage"
169+
class="uploaded-image"
154170
:src="backendURL + data.value"
155171
alt="employee pic"
156-
/>
172+
>
157173
<DxFileUploader
158174
ref="fileUploaderRef"
159175
:multiple="false"
160176
accept="image/*"
161177
upload-mode="instantly"
162178
:upload-url="backendURL + 'FileUpload/post'"
163179
@value-changed="onValueChanged"
164-
@uploaded="createUploadedHandler(data)"
180+
:on-uploaded="createUploadedHandler(data)"
165181
@upload-error="onUploadError"
166182
/>
167183
<DxButton
168-
class="retryButton"
169-
text="Retry"
184+
class="retry-button"
170185
:visible="retryButtonVisible"
171186
@click="onClick"
172-
/>
187+
>
188+
Retry
189+
</DxButton>
173190
</div>
174191
</template>
175192
</DxDataGrid>
@@ -194,15 +211,15 @@ function onSaved(_e: SavedEvent<Employee, number>): void {
194211
gap: 10px;
195212
}
196213
197-
.uploadedImage {
214+
.uploaded-image {
198215
max-width: 150px;
199216
max-height: 150px;
200217
border: 1px solid #ddd;
201218
border-radius: 4px;
202219
object-fit: cover;
203220
}
204221
205-
.retryButton {
222+
.retry-button {
206223
margin-top: 10px;
207224
align-self: flex-start;
208225
}

Vue/src/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const backendURL = "http://localhost:5020/";
1+
export const backendURL = 'http://localhost:5020/';

0 commit comments

Comments
 (0)