@dssp/project 0.0.27 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/pages/lib/select2-component.ts +12 -1
- package/client/pages/project/component/project-update-header.ts +85 -0
- package/client/pages/project/popup/popup-schedule-upload.ts +102 -0
- package/client/pages/project/project-list.ts +1 -0
- package/client/pages/project/project-plan-management.ts +3 -54
- package/client/pages/project/project-schedule.ts +60 -13
- package/client/pages/project/project-update.ts +4 -52
- package/dist-client/pages/lib/select2-component.js +12 -1
- package/dist-client/pages/lib/select2-component.js.map +1 -1
- package/dist-client/pages/project/component/project-update-header.d.ts +1 -0
- package/dist-client/pages/project/component/project-update-header.js +95 -0
- package/dist-client/pages/project/component/project-update-header.js.map +1 -0
- package/dist-client/pages/project/popup/popup-schedule-upload.d.ts +9 -0
- package/dist-client/pages/project/popup/popup-schedule-upload.js +105 -0
- package/dist-client/pages/project/popup/popup-schedule-upload.js.map +1 -0
- package/dist-client/pages/project/project-list.d.ts +1 -0
- package/dist-client/pages/project/project-list.js.map +1 -1
- package/dist-client/pages/project/project-plan-management.d.ts +1 -0
- package/dist-client/pages/project/project-plan-management.js +3 -53
- package/dist-client/pages/project/project-plan-management.js.map +1 -1
- package/dist-client/pages/project/project-schedule.d.ts +4 -0
- package/dist-client/pages/project/project-schedule.js +55 -12
- package/dist-client/pages/project/project-schedule.js.map +1 -1
- package/dist-client/pages/project/project-update.d.ts +1 -0
- package/dist-client/pages/project/project-update.js +4 -52
- package/dist-client/pages/project/project-update.js.map +1 -1
- package/dist-client/route.d.ts +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/dist-server/service/project/project-mutation.d.ts +2 -1
- package/dist-server/service/project/project-mutation.js +16 -0
- package/dist-server/service/project/project-mutation.js.map +1 -1
- package/dist-server/service/project/project-query.d.ts +1 -0
- package/dist-server/service/project/project-query.js +17 -0
- package/dist-server/service/project/project-query.js.map +1 -1
- package/dist-server/service/project/project-type.d.ts +4 -0
- package/dist-server/service/project/project-type.js +15 -1
- package/dist-server/service/project/project-type.js.map +1 -1
- package/dist-server/service/project/project.d.ts +1 -0
- package/dist-server/service/project/project.js +4 -0
- package/dist-server/service/project/project.js.map +1 -1
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/server/service/project/project-mutation.ts +16 -1
- package/server/service/project/project-query.ts +13 -0
- package/server/service/project/project-type.ts +9 -0
- package/server/service/project/project.ts +4 -0
|
@@ -8,6 +8,10 @@ export class Select2Component extends LitElement {
|
|
|
8
8
|
position: relative;
|
|
9
9
|
width: 300px;
|
|
10
10
|
border: 1px solid #000;
|
|
11
|
+
border-radius: 6px;
|
|
12
|
+
padding: 4px 16px;
|
|
13
|
+
font-size: 14px;
|
|
14
|
+
color: var(--md-sys-color-primary);
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
div[dropdown] {
|
|
@@ -18,6 +22,8 @@ export class Select2Component extends LitElement {
|
|
|
18
22
|
|
|
19
23
|
div[options] {
|
|
20
24
|
position: absolute;
|
|
25
|
+
left: 0;
|
|
26
|
+
top: 30px;
|
|
21
27
|
width: 100%;
|
|
22
28
|
border: 1px solid #ccc;
|
|
23
29
|
background-color: white;
|
|
@@ -30,6 +36,10 @@ export class Select2Component extends LitElement {
|
|
|
30
36
|
div[option] {
|
|
31
37
|
padding: 10px;
|
|
32
38
|
cursor: pointer;
|
|
39
|
+
border-bottom: 1px solid #ccc;
|
|
40
|
+
}
|
|
41
|
+
div[option]:last-child {
|
|
42
|
+
border-bottom: none;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
45
|
div[option]:hover {
|
|
@@ -48,10 +58,11 @@ export class Select2Component extends LitElement {
|
|
|
48
58
|
}
|
|
49
59
|
|
|
50
60
|
div[tag] {
|
|
51
|
-
background-color: #
|
|
61
|
+
background-color: #2e79be;
|
|
52
62
|
color: white;
|
|
53
63
|
padding: 5px 10px;
|
|
54
64
|
border-radius: 20px;
|
|
65
|
+
font-size: 13px;
|
|
55
66
|
display: inline-flex;
|
|
56
67
|
align-items: center;
|
|
57
68
|
cursor: pointer;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js'
|
|
2
|
+
import { css, html, LitElement } from 'lit'
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
4
|
+
import { ButtonContainerStyles, ScrollbarStyles } from '@operato/styles'
|
|
5
|
+
|
|
6
|
+
@customElement('project-update-header')
|
|
7
|
+
class ProjectUpdateHeader extends LitElement {
|
|
8
|
+
static styles = [
|
|
9
|
+
ButtonContainerStyles,
|
|
10
|
+
ScrollbarStyles,
|
|
11
|
+
css`
|
|
12
|
+
div[header] {
|
|
13
|
+
display: flex;
|
|
14
|
+
margin: 0px 20px;
|
|
15
|
+
|
|
16
|
+
h2 {
|
|
17
|
+
flex: 0.5;
|
|
18
|
+
color: #3f71a0;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
div[button-container] {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: end;
|
|
26
|
+
flex: 0.5;
|
|
27
|
+
|
|
28
|
+
md-elevated-button {
|
|
29
|
+
margin: 0px 3px;
|
|
30
|
+
|
|
31
|
+
--md-elevated-button-container-height: 35px;
|
|
32
|
+
--md-elevated-button-label-text-size: 16px;
|
|
33
|
+
--md-elevated-button-container-color: #0595e5;
|
|
34
|
+
|
|
35
|
+
--md-elevated-button-label-text-color: #fff;
|
|
36
|
+
--md-elevated-button-hover-label-text-color: #fff;
|
|
37
|
+
--md-elevated-button-pressed-label-text-color: #fff;
|
|
38
|
+
--md-elevated-button-focus-label-text-color: #fff;
|
|
39
|
+
--md-elevated-button-icon-color: #fff;
|
|
40
|
+
--md-elevated-button-hover-icon-color: #fff;
|
|
41
|
+
--md-elevated-button-pressed-icon-color: #fff;
|
|
42
|
+
--md-elevated-button-focus-icon-color: #fff;
|
|
43
|
+
|
|
44
|
+
&[green] {
|
|
45
|
+
--md-elevated-button-container-color: #42b382;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
`
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
@property({ type: String }) projectId: string = ''
|
|
53
|
+
@property({ type: String }) title: string = ''
|
|
54
|
+
|
|
55
|
+
render() {
|
|
56
|
+
const path = window.location.pathname
|
|
57
|
+
|
|
58
|
+
return html`
|
|
59
|
+
<div header>
|
|
60
|
+
<h2>${this.title}</h2>
|
|
61
|
+
<div button-container>
|
|
62
|
+
<md-elevated-button green @click=${this._dispatchEvent} ?disabled=${!this.projectId}>
|
|
63
|
+
<md-icon slot="icon">save</md-icon>정보 저장
|
|
64
|
+
</md-elevated-button>
|
|
65
|
+
<md-elevated-button
|
|
66
|
+
href=${`project-update/${this.projectId}`}
|
|
67
|
+
?disabled=${!this.projectId || path.includes('project-update/')}
|
|
68
|
+
>
|
|
69
|
+
<md-icon slot="icon">assignment</md-icon>프로젝트 정보 수정
|
|
70
|
+
</md-elevated-button>
|
|
71
|
+
<md-elevated-button
|
|
72
|
+
href=${`project-plan-management/${this.projectId}`}
|
|
73
|
+
?disabled=${!this.projectId || path.includes('project-plan-management/')}
|
|
74
|
+
>
|
|
75
|
+
<md-icon slot="icon">description</md-icon>도면 관리
|
|
76
|
+
</md-elevated-button>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
`
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private _dispatchEvent() {
|
|
83
|
+
this.dispatchEvent(new CustomEvent('custom-click'))
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { css, html, LitElement } from 'lit'
|
|
2
|
+
import { customElement, property } from 'lit/decorators.js'
|
|
3
|
+
import { client } from '@operato/graphql'
|
|
4
|
+
import { notify } from '@operato/layout'
|
|
5
|
+
import gql from 'graphql-tag'
|
|
6
|
+
import { Attachment } from '@things-factory/attachment-base'
|
|
7
|
+
|
|
8
|
+
@customElement('popup-schedule-upload')
|
|
9
|
+
export class PopupScheduleUpload extends LitElement {
|
|
10
|
+
static styles = [
|
|
11
|
+
css`
|
|
12
|
+
:host {
|
|
13
|
+
display: flex;
|
|
14
|
+
flex-direction: column;
|
|
15
|
+
background-color: #fff;
|
|
16
|
+
width: 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
div[body] {
|
|
20
|
+
flex: 1;
|
|
21
|
+
|
|
22
|
+
div[input-container] {
|
|
23
|
+
display: flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
gap: 25px;
|
|
27
|
+
background-color: #f7f7f7;
|
|
28
|
+
padding: 35px 27px 27px 27px;
|
|
29
|
+
|
|
30
|
+
ox-input-file {
|
|
31
|
+
height: 100px;
|
|
32
|
+
width: 120px;
|
|
33
|
+
line-height: 100%;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
div[button-container] {
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
justify-content: center;
|
|
41
|
+
margin-top: 20px;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
@property({ type: Object }) private scheduleTable: Attachment | undefined
|
|
48
|
+
@property({ type: String }) private projectId: string | undefined
|
|
49
|
+
|
|
50
|
+
render() {
|
|
51
|
+
const icon = this.scheduleTable ? '' : 'upload'
|
|
52
|
+
const description = this.scheduleTable?.name ? ' ' : '공정표 업로드'
|
|
53
|
+
|
|
54
|
+
return html`
|
|
55
|
+
<div body>
|
|
56
|
+
<div input-container>
|
|
57
|
+
<ox-input-file
|
|
58
|
+
icon=${icon}
|
|
59
|
+
label=${this.scheduleTable?.name || ''}
|
|
60
|
+
description=${description}
|
|
61
|
+
@change=${this._onChangeAttachment.bind(this)}
|
|
62
|
+
></ox-input-file>
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
<div button-container>
|
|
66
|
+
<md-outlined-button @click=${this._close}><md-icon slot="icon">cancel</md-icon>취소</md-outlined-button>
|
|
67
|
+
</div>
|
|
68
|
+
</div>
|
|
69
|
+
`
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private _close() {
|
|
73
|
+
history.back()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// 공정표 업로드
|
|
77
|
+
async _onChangeAttachment(e: CustomEvent) {
|
|
78
|
+
const file = e.detail[0] || null
|
|
79
|
+
|
|
80
|
+
const response = await client.mutate({
|
|
81
|
+
mutation: gql`
|
|
82
|
+
mutation UploadProjectScheduleTable($param: UploadProjectScheduleTable!) {
|
|
83
|
+
uploadProjectScheduleTable(param: $param)
|
|
84
|
+
}
|
|
85
|
+
`,
|
|
86
|
+
variables: {
|
|
87
|
+
param: {
|
|
88
|
+
projectId: this.projectId,
|
|
89
|
+
scheduleTable: file
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
context: {
|
|
93
|
+
hasUpload: true
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
if (!response.errors) {
|
|
98
|
+
notify({ message: '공정표가 업로드 되었습니다.' })
|
|
99
|
+
this.dispatchEvent(new CustomEvent('uploaded'))
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -16,6 +16,7 @@ import { openPopup } from '@operato/layout'
|
|
|
16
16
|
import gql from 'graphql-tag'
|
|
17
17
|
import { Building, BuildingLevel, Project } from './project-list'
|
|
18
18
|
import './popup/popup-plan-upload'
|
|
19
|
+
import './component/project-update-header'
|
|
19
20
|
|
|
20
21
|
@customElement('project-plan-management')
|
|
21
22
|
export class ProjectPlanManagement extends ScopedElementsMixin(PageView) {
|
|
@@ -53,44 +54,6 @@ export class ProjectPlanManagement extends ScopedElementsMixin(PageView) {
|
|
|
53
54
|
font-weight: bold;
|
|
54
55
|
}
|
|
55
56
|
|
|
56
|
-
div[header] {
|
|
57
|
-
display: flex;
|
|
58
|
-
margin: 0px 20px;
|
|
59
|
-
|
|
60
|
-
h2 {
|
|
61
|
-
flex: 0.5;
|
|
62
|
-
color: #3f71a0;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
div[button-container] {
|
|
66
|
-
display: flex;
|
|
67
|
-
align-items: center;
|
|
68
|
-
justify-content: end;
|
|
69
|
-
flex: 0.5;
|
|
70
|
-
|
|
71
|
-
md-elevated-button {
|
|
72
|
-
margin: 0px 3px;
|
|
73
|
-
|
|
74
|
-
--md-elevated-button-container-height: 35px;
|
|
75
|
-
--md-elevated-button-label-text-size: 16px;
|
|
76
|
-
--md-elevated-button-container-color: #0595e5;
|
|
77
|
-
|
|
78
|
-
--md-elevated-button-label-text-color: #fff;
|
|
79
|
-
--md-elevated-button-hover-label-text-color: #fff;
|
|
80
|
-
--md-elevated-button-pressed-label-text-color: #fff;
|
|
81
|
-
--md-elevated-button-focus-label-text-color: #fff;
|
|
82
|
-
--md-elevated-button-icon-color: #fff;
|
|
83
|
-
--md-elevated-button-hover-icon-color: #fff;
|
|
84
|
-
--md-elevated-button-pressed-icon-color: #fff;
|
|
85
|
-
--md-elevated-button-focus-icon-color: #fff;
|
|
86
|
-
|
|
87
|
-
&[green] {
|
|
88
|
-
--md-elevated-button-container-color: #42b382;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
57
|
div[body] {
|
|
95
58
|
display: grid;
|
|
96
59
|
grid-template-rows: 240px 1fr 60px;
|
|
@@ -247,20 +210,8 @@ export class ProjectPlanManagement extends ScopedElementsMixin(PageView) {
|
|
|
247
210
|
|
|
248
211
|
render() {
|
|
249
212
|
return html`
|
|
250
|
-
<
|
|
251
|
-
|
|
252
|
-
<div button-container>
|
|
253
|
-
<md-elevated-button green @click=${this._saveProject}>
|
|
254
|
-
<md-icon slot="icon">save</md-icon>정보 저장
|
|
255
|
-
</md-elevated-button>
|
|
256
|
-
<md-elevated-button href=${`project-update/${this.project.id}`}>
|
|
257
|
-
<md-icon slot="icon">assignment</md-icon>프로젝트 정보 수정
|
|
258
|
-
</md-elevated-button>
|
|
259
|
-
<md-elevated-button href=${`project-task-update/${this.project.id}`}>
|
|
260
|
-
<md-icon slot="icon">event_note</md-icon>공정표 관리
|
|
261
|
-
</md-elevated-button>
|
|
262
|
-
</div>
|
|
263
|
-
</div>
|
|
213
|
+
<project-update-header .projectId=${this.project.id || ''} title="도면 관리" @custom-click=${this._saveProject}>
|
|
214
|
+
</project-update-header>
|
|
264
215
|
|
|
265
216
|
<div body>
|
|
266
217
|
<div building-container>
|
|
@@ -415,8 +366,6 @@ export class ProjectPlanManagement extends ScopedElementsMixin(PageView) {
|
|
|
415
366
|
})
|
|
416
367
|
|
|
417
368
|
this.project = response.data?.project
|
|
418
|
-
|
|
419
|
-
console.log('init project : ', this.project)
|
|
420
369
|
}
|
|
421
370
|
|
|
422
371
|
private async _saveProject() {
|
|
@@ -11,10 +11,13 @@ import { customElement, query, state } from 'lit/decorators.js'
|
|
|
11
11
|
import { ScopedElementsMixin } from '@open-wc/scoped-elements'
|
|
12
12
|
import { client } from '@operato/graphql'
|
|
13
13
|
import { i18next } from '@operato/i18n'
|
|
14
|
-
|
|
14
|
+
import { openPopup } from '@operato/layout'
|
|
15
15
|
import gql from 'graphql-tag'
|
|
16
16
|
import { Project } from './project-list'
|
|
17
|
+
import { keyed } from 'lit/directives/keyed.js'
|
|
18
|
+
import { ScrollbarStyles } from '@operato/styles'
|
|
17
19
|
import '@operato/gantt/ox-gantt.js'
|
|
20
|
+
import './popup/popup-schedule-upload'
|
|
18
21
|
|
|
19
22
|
const TaskFragment = gql`
|
|
20
23
|
fragment TaskFragment on Task {
|
|
@@ -36,6 +39,7 @@ const TaskFragment = gql`
|
|
|
36
39
|
@customElement('project-schedule')
|
|
37
40
|
export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
38
41
|
static styles = [
|
|
42
|
+
ScrollbarStyles,
|
|
39
43
|
css`
|
|
40
44
|
:host {
|
|
41
45
|
display: flex;
|
|
@@ -137,11 +141,25 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
137
141
|
}
|
|
138
142
|
}
|
|
139
143
|
|
|
140
|
-
div[
|
|
144
|
+
div[construction-list-container] {
|
|
141
145
|
flex: 1;
|
|
146
|
+
display: flex;
|
|
142
147
|
border-radius: 5px;
|
|
143
148
|
border: 1px solid #cccccc80;
|
|
144
149
|
background-color: #fff;
|
|
150
|
+
padding: 8px 10px;
|
|
151
|
+
gap: 10px;
|
|
152
|
+
overflow-x: auto;
|
|
153
|
+
|
|
154
|
+
md-outlined-button {
|
|
155
|
+
--md-outlined-button-container-height: 30px;
|
|
156
|
+
--md-outlined-button-trailing-space: 15px;
|
|
157
|
+
--md-outlined-button-leading-space: 15px;
|
|
158
|
+
--md-outlined-button-label-text-color: #586878;
|
|
159
|
+
box-shadow: 1px 1px 1px #0000001a;
|
|
160
|
+
padding: 8px 16px;
|
|
161
|
+
font-weight: 700;
|
|
162
|
+
}
|
|
145
163
|
}
|
|
146
164
|
}
|
|
147
165
|
}
|
|
@@ -171,6 +189,7 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
171
189
|
@state() project: Project = { ...this.defaultProject }
|
|
172
190
|
@state() selectedBuildingIdx: number = 0
|
|
173
191
|
@state() tasks
|
|
192
|
+
@state() constructionTypeList = []
|
|
174
193
|
|
|
175
194
|
@state() private fromDate = '2024-01-01'
|
|
176
195
|
@state() private toDate = '2024-12-31'
|
|
@@ -213,13 +232,7 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
213
232
|
<div header>
|
|
214
233
|
<h2>${this.project.name}</h2>
|
|
215
234
|
<div button-container>
|
|
216
|
-
<md-elevated-button
|
|
217
|
-
<md-icon slot="icon">assignment</md-icon>프로젝트 정보 수정
|
|
218
|
-
</md-elevated-button>
|
|
219
|
-
<md-elevated-button href=${`project-plan-management/${this.project.id}`}>
|
|
220
|
-
<md-icon slot="icon">description</md-icon>도면 관리
|
|
221
|
-
</md-elevated-button>
|
|
222
|
-
<md-elevated-button href=${`project-task-update/${this.project.id}`}>
|
|
235
|
+
<md-elevated-button @click=${this._openUploadSchedulePopup}>
|
|
223
236
|
<md-icon slot="icon">event_note</md-icon>공정표 관리
|
|
224
237
|
</md-elevated-button>
|
|
225
238
|
</div>
|
|
@@ -231,9 +244,7 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
231
244
|
to-date=${new Date(this.toDate).toISOString().split('T')[0]}
|
|
232
245
|
.timeScale=${this.timeScale}
|
|
233
246
|
.tasks=${this.tasks}
|
|
234
|
-
@date-range-selected=${
|
|
235
|
-
console.log('date-range-selected', e.detail)
|
|
236
|
-
}}
|
|
247
|
+
@date-range-selected=${this.onRangeSelected}
|
|
237
248
|
@task-clicked=${(e: CustomEvent) => {
|
|
238
249
|
console.log('task-clicked', e.detail)
|
|
239
250
|
}}
|
|
@@ -253,7 +264,12 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
253
264
|
<input type="date" name="endDate" project .value=${this.project.endDate || ''} max="9999-12-31" />
|
|
254
265
|
</div>
|
|
255
266
|
</div>
|
|
256
|
-
<div
|
|
267
|
+
<div construction-list-container>
|
|
268
|
+
${this.constructionTypeList?.map(
|
|
269
|
+
(constructionType: any) =>
|
|
270
|
+
html` <md-outlined-button id=${constructionType.id}>${constructionType.title}</md-outlined-button>`
|
|
271
|
+
)}
|
|
272
|
+
</div>
|
|
257
273
|
</div>
|
|
258
274
|
</div>
|
|
259
275
|
`
|
|
@@ -286,6 +302,10 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
286
302
|
}
|
|
287
303
|
}
|
|
288
304
|
}
|
|
305
|
+
scheduleTable {
|
|
306
|
+
id
|
|
307
|
+
name
|
|
308
|
+
}
|
|
289
309
|
buildingComplex {
|
|
290
310
|
id
|
|
291
311
|
planXScale
|
|
@@ -333,4 +353,31 @@ export class ProjectSchedule extends ScopedElementsMixin(PageView) {
|
|
|
333
353
|
this.fromDate = this.inputStartDate.value
|
|
334
354
|
this.toDate = this.inputEndDate.value
|
|
335
355
|
}
|
|
356
|
+
|
|
357
|
+
onRangeSelected(e: CustomEvent) {
|
|
358
|
+
const selectedFromDate = new Date(e.detail.start + 'T00:00:00.000Z')
|
|
359
|
+
const selectedToDate = new Date(e.detail.end + 'T23:59:59.000Z')
|
|
360
|
+
|
|
361
|
+
this.constructionTypeList = this.tasks.filter(constuction => {
|
|
362
|
+
const constuctionStartDate = new Date(constuction.startDate)
|
|
363
|
+
const constuctionEndDate = new Date(constuction.endDate)
|
|
364
|
+
|
|
365
|
+
return constuctionStartDate <= selectedToDate && constuctionEndDate >= selectedFromDate
|
|
366
|
+
})
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
private _openUploadSchedulePopup() {
|
|
370
|
+
openPopup(
|
|
371
|
+
html`<popup-schedule-upload
|
|
372
|
+
.projectId=${this.projectId}
|
|
373
|
+
.scheduleTable=${this.project?.scheduleTable}
|
|
374
|
+
@uploaded=${() => this.initProject(this.projectId)}
|
|
375
|
+
></popup-schedule-upload>`,
|
|
376
|
+
{
|
|
377
|
+
backdrop: true,
|
|
378
|
+
size: 'medium',
|
|
379
|
+
title: `공정표 업로드`
|
|
380
|
+
}
|
|
381
|
+
)
|
|
382
|
+
}
|
|
336
383
|
}
|
|
@@ -12,6 +12,7 @@ import { notify } from '@operato/layout'
|
|
|
12
12
|
import gql from 'graphql-tag'
|
|
13
13
|
import { Project } from './project-list'
|
|
14
14
|
import '../lib/select2-component'
|
|
15
|
+
import './component/project-update-header'
|
|
15
16
|
|
|
16
17
|
@customElement('project-update')
|
|
17
18
|
export class ProjectUpdate extends ScopedElementsMixin(PageView) {
|
|
@@ -55,44 +56,6 @@ export class ProjectUpdate extends ScopedElementsMixin(PageView) {
|
|
|
55
56
|
padding: 0;
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
div[header] {
|
|
59
|
-
display: flex;
|
|
60
|
-
margin: 0px 20px;
|
|
61
|
-
|
|
62
|
-
h2 {
|
|
63
|
-
flex: 0.5;
|
|
64
|
-
color: #3f71a0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
div[button-container] {
|
|
68
|
-
display: flex;
|
|
69
|
-
align-items: center;
|
|
70
|
-
justify-content: end;
|
|
71
|
-
flex: 0.5;
|
|
72
|
-
|
|
73
|
-
md-elevated-button {
|
|
74
|
-
margin: 0px 3px;
|
|
75
|
-
|
|
76
|
-
--md-elevated-button-container-height: 35px;
|
|
77
|
-
--md-elevated-button-label-text-size: 16px;
|
|
78
|
-
--md-elevated-button-container-color: #0595e5;
|
|
79
|
-
|
|
80
|
-
--md-elevated-button-label-text-color: #fff;
|
|
81
|
-
--md-elevated-button-hover-label-text-color: #fff;
|
|
82
|
-
--md-elevated-button-pressed-label-text-color: #fff;
|
|
83
|
-
--md-elevated-button-focus-label-text-color: #fff;
|
|
84
|
-
--md-elevated-button-icon-color: #fff;
|
|
85
|
-
--md-elevated-button-hover-icon-color: #fff;
|
|
86
|
-
--md-elevated-button-pressed-icon-color: #fff;
|
|
87
|
-
--md-elevated-button-focus-icon-color: #fff;
|
|
88
|
-
|
|
89
|
-
&[green] {
|
|
90
|
-
--md-elevated-button-container-color: #42b382;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
59
|
div[body] {
|
|
97
60
|
display: flex;
|
|
98
61
|
margin: 0px 25px 25px 25px;
|
|
@@ -266,20 +229,9 @@ export class ProjectUpdate extends ScopedElementsMixin(PageView) {
|
|
|
266
229
|
|
|
267
230
|
render() {
|
|
268
231
|
return html`
|
|
269
|
-
<
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
<md-elevated-button green @click=${this._saveProject}>
|
|
273
|
-
<md-icon slot="icon">save</md-icon>정보 저장
|
|
274
|
-
</md-elevated-button>
|
|
275
|
-
<md-elevated-button href=${`project-plan-management/${this.project.id}`}>
|
|
276
|
-
<md-icon slot="icon">description</md-icon>도면 관리
|
|
277
|
-
</md-elevated-button>
|
|
278
|
-
<md-elevated-button href=${`project-task-update/${this.project.id}`}>
|
|
279
|
-
<md-icon slot="icon">event_note</md-icon>공정표 관리
|
|
280
|
-
</md-elevated-button>
|
|
281
|
-
</div>
|
|
282
|
-
</div>
|
|
232
|
+
<project-update-header .projectId=${this.project.id || ''} title="프로젝트 정보 관리" @custom-click=${this._saveProject}>
|
|
233
|
+
</project-update-header>
|
|
234
|
+
|
|
283
235
|
<div body>
|
|
284
236
|
<div project-info>
|
|
285
237
|
<h3>기본 정보</h3>
|
|
@@ -89,6 +89,10 @@ Select2Component.styles = css `
|
|
|
89
89
|
position: relative;
|
|
90
90
|
width: 300px;
|
|
91
91
|
border: 1px solid #000;
|
|
92
|
+
border-radius: 6px;
|
|
93
|
+
padding: 4px 16px;
|
|
94
|
+
font-size: 14px;
|
|
95
|
+
color: var(--md-sys-color-primary);
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
div[dropdown] {
|
|
@@ -99,6 +103,8 @@ Select2Component.styles = css `
|
|
|
99
103
|
|
|
100
104
|
div[options] {
|
|
101
105
|
position: absolute;
|
|
106
|
+
left: 0;
|
|
107
|
+
top: 30px;
|
|
102
108
|
width: 100%;
|
|
103
109
|
border: 1px solid #ccc;
|
|
104
110
|
background-color: white;
|
|
@@ -111,6 +117,10 @@ Select2Component.styles = css `
|
|
|
111
117
|
div[option] {
|
|
112
118
|
padding: 10px;
|
|
113
119
|
cursor: pointer;
|
|
120
|
+
border-bottom: 1px solid #ccc;
|
|
121
|
+
}
|
|
122
|
+
div[option]:last-child {
|
|
123
|
+
border-bottom: none;
|
|
114
124
|
}
|
|
115
125
|
|
|
116
126
|
div[option]:hover {
|
|
@@ -129,10 +139,11 @@ Select2Component.styles = css `
|
|
|
129
139
|
}
|
|
130
140
|
|
|
131
141
|
div[tag] {
|
|
132
|
-
background-color: #
|
|
142
|
+
background-color: #2e79be;
|
|
133
143
|
color: white;
|
|
134
144
|
padding: 5px 10px;
|
|
135
145
|
border-radius: 20px;
|
|
146
|
+
font-size: 13px;
|
|
136
147
|
display: inline-flex;
|
|
137
148
|
align-items: center;
|
|
138
149
|
cursor: pointer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select2-component.js","sourceRoot":"","sources":["../../../client/pages/lib/select2-component.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG3D,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,UAAU;IAAzC;;
|
|
1
|
+
{"version":3,"file":"select2-component.js","sourceRoot":"","sources":["../../../client/pages/lib/select2-component.ts"],"names":[],"mappings":"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","sourcesContent":["import { LitElement, html, css } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\n@customElement('select2-component')\nexport class Select2Component extends LitElement {\n static styles = css`\n div[select-container] {\n position: relative;\n width: 300px;\n border: 1px solid #000;\n border-radius: 6px;\n padding: 4px 16px;\n font-size: 14px;\n color: var(--md-sys-color-primary);\n }\n\n div[dropdown] {\n border: 1px solid #ccc;\n padding: 5px;\n cursor: pointer;\n }\n\n div[options] {\n position: absolute;\n left: 0;\n top: 30px;\n width: 100%;\n border: 1px solid #ccc;\n background-color: white;\n max-height: 150px;\n overflow-y: auto;\n display: block;\n z-index: 1;\n }\n\n div[option] {\n padding: 10px;\n cursor: pointer;\n border-bottom: 1px solid #ccc;\n }\n div[option]:last-child {\n border-bottom: none;\n }\n\n div[option]:hover {\n background-color: #f0f0f0;\n }\n\n div[option][selected] {\n background-color: #d3f9d8;\n }\n\n div[selected-tags] {\n display: flex;\n flex-wrap: wrap;\n gap: 5px;\n margin-top: 10px;\n }\n\n div[tag] {\n background-color: #2e79be;\n color: white;\n padding: 5px 10px;\n border-radius: 20px;\n font-size: 13px;\n display: inline-flex;\n align-items: center;\n cursor: pointer;\n }\n\n span[tag-close] {\n margin-left: 8px;\n }\n `\n\n @property({ type: String }) placeholder: string = ''\n @property({ type: Array }) options: Array<{ name: string; value: string }> = []\n @property({ type: Array }) selectedValues: string[] = []\n\n @state() showOptions: boolean = false\n\n get selectedItems() {\n return this.selectedValues.map(id => this.options.find(option => option.value === id)).filter(Boolean)\n }\n\n connectedCallback() {\n super.connectedCallback()\n document.addEventListener('click', this._handleOutsideClick)\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n document.removeEventListener('click', this._handleOutsideClick)\n }\n\n private _handleOutsideClick = (event: MouseEvent) => {\n const path = event.composedPath()\n if (!path.includes(this)) {\n this.showOptions = false\n }\n }\n\n private _toggleOptions() {\n this.showOptions = !this.showOptions\n }\n\n private _handleSelect(optionValue: string) {\n if (this.selectedValues.includes(optionValue)) {\n // 이미 선택된 옵션을 선택한 경우 해제\n this.selectedValues = this.selectedValues.filter(value => value !== optionValue)\n } else {\n // 선택되지 않은 옵션 추가\n this.selectedValues = [...this.selectedValues, optionValue]\n }\n\n this.showOptions = false\n this._dispatchEvent(this.selectedValues)\n }\n\n private _handleRemove(tagValue: string) {\n this.selectedValues = this.selectedValues.filter(value => value !== tagValue)\n this._dispatchEvent(this.selectedValues)\n }\n\n private _dispatchEvent(selectedValues: string[]) {\n this.dispatchEvent(\n new CustomEvent('selection-changed', {\n detail: { selectedValues }, // ID 배열을 부모로 전달\n bubbles: true,\n composed: true\n })\n )\n }\n\n render() {\n return html`\n <div select-container>\n <div tags @click=\"${this._toggleOptions}\">${this.placeholder}</div>\n ${this.showOptions\n ? html`\n <div options>\n ${this.options.map(\n option => html`\n <div\n option\n ?selected=${this.selectedValues.includes(option.value)}\n @click=${() => this._handleSelect(option.value)}\n >\n ${option.name}\n </div>\n `\n )}\n </div>\n `\n : ''}\n </div>\n\n <div selected-tags>\n ${this.selectedItems.map(\n (tag: any) => html`\n <div tag @click=${() => this._handleRemove(tag.value)}>\n ${tag!.name}\n <span tag-close>×</span>\n </div>\n `\n )}\n </div>\n `\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@material/web/icon/icon.js';
|