Skip to content

Commit 787038f

Browse files
Merge branch 'main' of github.com:VovaStelmashchuk/nest2d
2 parents 10318dc + 281fa8b commit 787038f

File tree

6 files changed

+160
-54
lines changed

6 files changed

+160
-54
lines changed

components/DxfViewerComponent.vue

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
<template>
2-
<div class="dxf-viewer-container" ref="containerRef">
3-
<div v-if="isLoading" class="loading-overlay">
4-
<MainLoader />
2+
<div
3+
ref="containerRef"
4+
:class="containerClasses"
5+
class="dxf-viewer-container"
6+
>
7+
<div
8+
v-if="isLoading"
9+
class="loading-overlay"
10+
>
11+
<MainLoader :size="sizeType.s" />
512
</div>
6-
<div v-if="error" class="error-overlay">
13+
<div
14+
v-if="error"
15+
class="error-overlay"
16+
>
717
Err
818
</div>
919
</div>
1020
</template>
1121

1222
<script setup>
23+
import { defaultSizeType, sizeType } from "~~/constants/size.constants";
1324
1425
const props = defineProps({
26+
size: {
27+
type: String,
28+
default: defaultSizeType
29+
},
1530
dxfUrl: {
1631
type: String,
1732
default: null
@@ -53,6 +68,10 @@ const clearViewer = () => {
5368
}
5469
}
5570
71+
const containerClasses = computed(() => ({
72+
[`dxf-viewer-container--size-${unref(props.size)}`]: Boolean(unref(props.size))
73+
}))
74+
5675
onMounted(async () => {
5776
await nextTick()
5877
@@ -99,11 +118,13 @@ defineExpose({
99118
</script>
100119

101120
<style scoped lang="scss">
121+
$loading: '.loading-overlay';
122+
$error: '.error-overlay';
123+
102124
.dxf-viewer-container {
103125
position: relative;
104126
max-height: 100%;
105127
max-width: 100%;
106-
width: 100%;
107128
min-height: 320px;
108129
border-radius: 8px;
109130
display: flex;
@@ -117,6 +138,17 @@ defineExpose({
117138
max-height: 100%;
118139
width: 100%;
119140
}
141+
142+
&--size-s {
143+
border-radius: 6px;
144+
145+
#{$loading} {
146+
border-radius: 6px;
147+
}
148+
#{$error} {
149+
border-radius: 6px;
150+
}
151+
}
120152
}
121153
122154
.loading-overlay {

components/FileModal.vue

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
<template>
22
<DialogWrapper>
3-
<div class="modal">
4-
<!-- {{ fileModalData.svgUrl }} -->
5-
3+
<div class="modal">
64
<div class="modal__wrapper">
75
<FileParts :class="partsClasses" :parts="fileModalData.parts" class="modal__parts"/>
8-
<SvgDisplay
9-
:src="fileModalData.svgUrl"
6+
<DxfViewerComponent
7+
:key="`dxf-0-${isFullScreen}`"
8+
:dxfUrl="fileModalData.dxfUrl"
9+
:isFullScreen="isFullScreen"
1010
:class="displayClasses"
11-
@click="updateFullScreen"
12-
class="modal__display"
11+
class="modal__display"
1312
/>
1413
<MainButton
1514
label="fullscreen"

components/ResultModal.vue

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,19 @@
3333
class="controls__next"
3434
/>
3535
</div>
36-
3736
<div class="modal__wrapper">
38-
<div v-if="isHaveError" :class="placeholderClasses" class="modal__placeholder">
37+
<div
38+
v-if="isHaveError"
39+
:class="placeholderClasses"
40+
class="modal__placeholder"
41+
>
3942
Err
4043
</div>
4144
<template v-else-if="resultModalData.isMultiSheet">
4245
<DxfViewerComponent
46+
:key="`dxf-${activePart}-${isFullScreen}`"
4347
:dxfUrl="resultModalData.dxfs[activePart]"
48+
:isFullScreen="isFullScreen"
4449
:class="displayClasses"
4550
class="modal__display"
4651
/>
@@ -57,13 +62,22 @@
5762
</template>
5863
<DxfViewerComponent
5964
v-else
65+
:key="`dxf-0-${isFullScreen}`"
6066
:dxfUrl="resultModalData.dxfs[0]"
67+
:isFullScreen="isFullScreen"
6168
:class="displayClasses"
6269
class="modal__display"
6370
/>
64-
<MainButton v-if="!isHaveError" label="fullscreen" :size="sizeType.s" :theme="themeType.primary"
65-
:isLabelShow="false" :icon="iconType.fullscreen" @click="updateFullScreen"
66-
class="modal__fullscreen" />
71+
<MainButton
72+
v-if="!isHaveError"
73+
label="fullscreen"
74+
:size="sizeType.s"
75+
:theme="themeType.primary"
76+
:isLabelShow="false"
77+
:icon="iconType.fullscreen"
78+
@click="updateFullScreen"
79+
class="modal__fullscreen"
80+
/>
6781
</div>
6882
<div class="modal__name modal__info info">
6983
<template v-if="isHaveError">
@@ -83,8 +97,14 @@
8397
{{ name }}
8498
</template>
8599
</div>
86-
<div v-if="!isHaveError" class="modal__info info">
87-
<span v-if="resultModalData.requested === resultModalData.placed" class="info__label">
100+
<div
101+
v-if="!isHaveError"
102+
class="modal__info info"
103+
>
104+
<span
105+
v-if="resultModalData.requested === resultModalData.placed"
106+
class="info__label"
107+
>
88108
All details are placed
89109
</span>
90110
<template v-else>
@@ -116,8 +136,12 @@
116136
:size="sizeType.s"
117137
:theme="themeType.primary"
118138
/>
119-
<MainButton label="Try again" :size="sizeType.s" :theme="themeType.secondary"
120-
@click="resultDialog = false" />
139+
<MainButton
140+
label="Try again"
141+
:size="sizeType.s"
142+
:theme="themeType.secondary"
143+
@click="resultDialog = false"
144+
/>
121145
</div>
122146
</div>
123147
</DialogWrapper>

components/SvgDisplay.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
<script setup>
1515
import { defaultSizeType } from "~~/constants/size.constants";
16-
import { computed } from 'vue';
1716
1817
const { svgContent, src, size } = defineProps({
1918
svgContent: {

components/UserResultItem.vue

Lines changed: 78 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,81 +1,118 @@
11
<template>
22
<div class="result">
33
<template v-if="isResultNexting">
4-
<MainLoader :size="sizeType.s" :theme="themeType.secondary" class="result__display" />
4+
<MainLoader
5+
:size="sizeType.s"
6+
:theme="themeType.secondary"
7+
class="result__display"
8+
/>
59
<p class="result__text">
6-
Nesting</p>
10+
Nesting
11+
</p>
712
</template>
813
<template v-else>
914
<div v-if="isResultFailed" class="result__placeholder">
1015
Err
1116
</div>
1217
<template v-else>
13-
<div class="result__svg-row">
14-
<SvgDisplay v-for="(svg, idx) in result.svgs" :key="svg + idx" :size="sizeType.s" :src="svg"
15-
class="result__display" />
18+
<div
19+
:class="svgRowClasses"
20+
class="result__svg-row"
21+
>
22+
<SvgDisplay
23+
v-for="(svg, svgIndex) in result.svgs"
24+
:key="`svg-${svgIndex}`"
25+
:src="svg"
26+
:size="sizeType.s"
27+
class="result__display"
28+
/>
1629
</div>
1730
</template>
1831
<p class="result__name">
1932
{{ result.slug }}.dxf
2033
</p>
2134
<div class="result__controls controls">
22-
<MainButton v-if="isResultCompleted" :href="downloadUrl" :label="downloadButtonText" tag="a"
23-
:size="sizeType.s" :theme="themeType.primary" class="controls__download" @click="onDownload" />
35+
<MainButton
36+
v-if="isResultCompleted"
37+
:href="downloadUrl"
38+
:label="downloadButtonText"
39+
tag="a"
40+
:size="sizeType.s"
41+
:theme="themeType.primary"
42+
class="controls__download"
43+
@click="onDownload"
44+
/>
2445
</div>
25-
<button @click="openModal()" class="result__area" />
46+
<button
47+
type="button"
48+
@click="openModal"
49+
class="result__area"
50+
aria-label="Open result details"
51+
/>
2652
</template>
2753
</div>
2854
</template>
55+
2956
<script setup>
3057
import { sizeType } from '~~/constants/size.constants';
3158
import { themeType } from '~~/constants/theme.constants';
3259
import { statusType } from "~~/constants/status.constants";
3360
import { trackEvent } from '~~/utils/track';
34-
import { computed, unref } from "vue";
61+
import { computed } from "vue";
3562
36-
const { result } = defineProps({
63+
const props = defineProps({
3764
result: {
3865
type: Object,
3966
required: true
4067
}
41-
})
68+
});
4269
4370
const emit = defineEmits(["openModal"]);
4471
4572
const isMultiSheet = computed(() => {
46-
return unref(result).isMultiSheet
47-
})
73+
return props.result?.isMultiSheet ?? false;
74+
});
4875
4976
const downloadUrl = computed(() => {
50-
return unref(result).downloadUrl
51-
})
77+
return props.result?.downloadUrl ?? '';
78+
});
5279
5380
const downloadButtonText = computed(() => {
54-
if (isMultiSheet.value) {
55-
return 'Download All'
56-
}
57-
return 'Download'
58-
})
81+
return isMultiSheet.value ? 'Download All' : 'Download';
82+
});
83+
84+
const hasMultipleSvgs = computed(() => {
85+
return (props.result?.svgs?.length ?? 0) > 1;
86+
});
87+
88+
const svgRowClasses = computed(() => {
89+
return ['result__svg-row', { 'result__svg-row--multi': hasMultipleSvgs.value }];
90+
});
5991
6092
const isResultNexting = computed(() => {
61-
return [statusType.unfinished, statusType.pending].includes(unref(result).status)
62-
})
93+
const status = props.result?.status;
94+
return status === statusType.unfinished || status === statusType.pending;
95+
});
96+
6397
const isResultFailed = computed(() => {
64-
return unref(result).status === statusType.failed
65-
})
98+
return props.result?.status === statusType.failed;
99+
});
100+
66101
const isResultCompleted = computed(() => {
67-
return unref(result).status === statusType.completed || unref(result).status === statusType.done
68-
})
102+
const status = props.result?.status;
103+
return status === statusType.completed || status === statusType.done;
104+
});
105+
69106
const openModal = () => {
70-
emit('openModal')
71-
}
107+
emit('openModal');
108+
};
72109
73110
const onDownload = () => {
74111
trackEvent('click_download_button', {
75-
slug: unref(result).slug,
112+
slug: props.result?.slug,
76113
isMultiSheet: isMultiSheet.value
77-
})
78-
}
114+
});
115+
};
79116
</script>
80117
<style lang="scss" scoped>
81118
.result {
@@ -90,15 +127,21 @@ const onDownload = () => {
90127
&__svg-row {
91128
max-width: 128px;
92129
display: grid;
93-
grid-template-columns: repeat(3, 1fr);
130+
grid-template-columns: 1fr;
94131
gap: 4px;
95132
margin-bottom: 8px;
133+
134+
&--multi {
135+
grid-template-columns: repeat(3, 1fr);
136+
}
96137
}
97138
98139
&__display,
99140
&__placeholder {
100141
width: 40px;
101142
height: 40px;
143+
min-height: 40px;
144+
overflow: hidden;
102145
}
103146
104147
&__placeholder {
@@ -138,6 +181,9 @@ const onDownload = () => {
138181
bottom: 0;
139182
left: 0;
140183
cursor: pointer;
184+
border: none;
185+
background: transparent;
186+
padding: 0;
141187
}
142188
143189
&__controls {

server/api/project/[slug]/index.get.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ const mapFileToUi = (file) => {
4545
? `/api/files/project/svg/${file.svgFileSlug}`
4646
: null;
4747

48+
const dxfUrl =
49+
file.processingStatus === "completed"
50+
? `/api/files/project/dxf/${file.slug}`
51+
: null;
52+
4853
let status;
4954
if (file.processingStatus === "completed") {
5055
status = "done";
@@ -67,6 +72,7 @@ const mapFileToUi = (file) => {
6772
slug: file.slug,
6873
name: file.name,
6974
svgUrl: svgUrl,
75+
dxfUrl: dxfUrl,
7076
processingStatus: status,
7177
parts: uiParts,
7278
};

0 commit comments

Comments
 (0)