@things-factory/quotation 8.0.40 → 9.0.0-9.0.0-beta.59.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/quotation",
3
- "version": "8.0.40",
3
+ "version": "9.0.0-9.0.0-beta.59.0",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -27,11 +27,11 @@
27
27
  "migration:create": "node ../../node_modules/typeorm/cli.js migration:create ./server/migrations/migration"
28
28
  },
29
29
  "dependencies": {
30
- "@operato/graphql": "^8.0.0",
31
- "@operato/shell": "^8.0.0",
32
- "@things-factory/auth-base": "^8.0.38",
33
- "@things-factory/shell": "^8.0.38",
34
- "@things-factory/worklist": "^8.0.40"
30
+ "@operato/graphql": "^9.0.0-beta",
31
+ "@operato/shell": "^9.0.0-beta",
32
+ "@things-factory/auth-base": "^9.0.0-9.0.0-beta.59.0",
33
+ "@things-factory/shell": "^9.0.0-9.0.0-beta.59.0",
34
+ "@things-factory/worklist": "^9.0.0-9.0.0-beta.59.0"
35
35
  },
36
- "gitHead": "6f97ca5dc8aab9acaeebbd3caace0c76bab2676d"
36
+ "gitHead": "cf6ee84b991f469a4e71198b0e6314b45e9e10b8"
37
37
  }
@@ -1 +0,0 @@
1
- export const UPDATE_QUOTATION = 'UPDATE_QUOTATION'
@@ -1,90 +0,0 @@
1
- /*
2
- Add the following line to clinet/bootstrap.ts so that activity editor can be registered when loading a module.
3
- --
4
- import './activities/quotation-edit.js' // refered by the activity template (activity-quotation) on server
5
- */
6
-
7
- import '../components/quotation-edit.js'
8
-
9
- import gql from 'graphql-tag'
10
- import { css, html, LitElement } from 'lit'
11
- import { customElement, property, query, state } from 'lit/decorators.js'
12
-
13
- import { client } from '@operato/graphql'
14
- import { i18next, localize } from '@operato/i18n'
15
- import { ScrollbarStyles } from '@operato/styles'
16
-
17
- // import { QuotationView } from '../components/quotation-edit.js'
18
-
19
- @customElement('activity-quotation-edit')
20
- export class ActivityQuotationView extends localize(i18next)(LitElement) {
21
- static styles = [
22
- ScrollbarStyles,
23
- css`
24
- :host {
25
- display: flex;
26
- flex-direction: column;
27
-
28
- background-color: var(--md-sys-color-surface);
29
- }
30
-
31
- quotation-edit {
32
- flex: 1;
33
- padding: 10px;
34
- overflow: auto;
35
- }
36
- `
37
- ]
38
-
39
- @property({ type: Object }) input?: any
40
- @property({ type: Object }) output?: any
41
-
42
- @state() quotation?: any //Quotation
43
-
44
- // @query('quotation-edit') quotationView!: QuotationView
45
-
46
- render() {
47
- return html`
48
- <quotation-edit .quotation=${this.quotation} .value=${this.output} @change=${this.onChange}></quotation-edit>
49
- `
50
- }
51
-
52
- async onChange() {
53
- // this.output = this.quotationView.value
54
-
55
- this.dispatchEvent(
56
- new CustomEvent('change', {
57
- detail: this.output
58
- })
59
- )
60
- }
61
-
62
- updated(changes) {
63
- if (changes.has('input')) {
64
- this.fetchQuotation()
65
- }
66
- }
67
-
68
- async fetchQuotation() {
69
- const id = this.input.quotationId
70
-
71
- if (id) {
72
- const response = await client.query({
73
- query: gql`
74
- query ($id: String!) {
75
- quotation(id: $id) {
76
- id
77
- name
78
- description
79
- }
80
- }
81
- `,
82
- variables: {
83
- id
84
- }
85
- })
86
-
87
- this.quotation = response.data.quotation
88
- }
89
- }
90
- }
@@ -1,90 +0,0 @@
1
- /*
2
- Add the following line to clinet/bootstrap.ts so that activity view can be registered when loading a module.
3
- --
4
- import './activities/quotation-view.js' // refered by the activity template (activity-data-collect) on server
5
- */
6
-
7
- import '../components/quotation-view.js'
8
-
9
- import gql from 'graphql-tag'
10
- import { css, html, LitElement } from 'lit'
11
- import { customElement, property, query, state } from 'lit/decorators.js'
12
-
13
- import { client } from '@operato/graphql'
14
- import { i18next, localize } from '@operato/i18n'
15
- import { ScrollbarStyles } from '@operato/styles'
16
-
17
- // import { QuotationView } from '../components/quotation-view.js'
18
-
19
- @customElement('activity-quotation-view')
20
- export class ActivityQuotationView extends localize(i18next)(LitElement) {
21
- static styles = [
22
- ScrollbarStyles,
23
- css`
24
- :host {
25
- display: flex;
26
- flex-direction: column;
27
-
28
- background-color: var(--md-sys-color-surface);
29
- }
30
-
31
- quotation-view {
32
- flex: 1;
33
- padding: 10px;
34
- overflow: auto;
35
- }
36
- `
37
- ]
38
-
39
- @property({ type: Object }) input?: any
40
- @property({ type: Object }) output?: any
41
-
42
- @state() quotation?: any //Quotation
43
-
44
- // @query('quotation-view') quotationView!: QuotationView
45
-
46
- render() {
47
- return html`
48
- <quotation-view .quotation=${this.quotation} .value=${this.output} @change=${this.onChange}></quotation-view>
49
- `
50
- }
51
-
52
- async onChange() {
53
- // this.output = this.quotationView.value
54
-
55
- this.dispatchEvent(
56
- new CustomEvent('change', {
57
- detail: this.output
58
- })
59
- )
60
- }
61
-
62
- updated(changes) {
63
- if (changes.has('input')) {
64
- this.fetchQuotation()
65
- }
66
- }
67
-
68
- async fetchQuotation() {
69
- const id = this.input.quotationId
70
-
71
- if (id) {
72
- const response = await client.query({
73
- query: gql`
74
- query ($id: String!) {
75
- quotation(id: $id) {
76
- id
77
- name
78
- description
79
- }
80
- }
81
- `,
82
- variables: {
83
- id
84
- }
85
- })
86
-
87
- this.quotation = response.data.quotation
88
- }
89
- }
90
- }
@@ -1,8 +0,0 @@
1
- import { store } from '@operato/shell'
2
- import quotation from './reducers/main'
3
-
4
- export default function bootstrap() {
5
- store.addReducers({
6
- quotation
7
- })
8
- }
package/client/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './actions/main'
@@ -1,25 +0,0 @@
1
- import { html } from 'lit'
2
- import { customElement, property } from 'lit/decorators.js'
3
- import { connect } from 'pwa-helpers/connect-mixin.js'
4
- import { store, PageView } from '@operato/shell'
5
-
6
- const logo = new URL('/assets/images/hatiolab-logo.png', import.meta.url).href
7
-
8
- @customElement('quotation-main')
9
- class QuotationMain extends connect(store)(PageView) {
10
- @property({ type: String }) quotation?: string
11
-
12
- render() {
13
- return html`
14
- <section>
15
- <h2>Quotation</h2>
16
- <img src=${logo}>
17
- </section>
18
- `
19
- }
20
-
21
- stateChanged(state) {
22
- this.quotation = state.quotation.state_main
23
- }
24
- }
25
-
@@ -1,87 +0,0 @@
1
- import '@material/web/icon/icon.js'
2
- import '@operato/data-grist'
3
-
4
- import gql from 'graphql-tag'
5
- import { css, html, LitElement } from 'lit'
6
- import { property } from 'lit/decorators.js'
7
-
8
- import { client } from '@operato/graphql'
9
- import { i18next } from '@operato/i18n'
10
- import { isMobileDevice } from '@operato/utils'
11
- import { CommonHeaderStyles } from '@operato/styles'
12
-
13
- export class QuotationImporter extends LitElement {
14
- static styles = [
15
- CommonHeaderStyles,
16
- css`
17
- :host {
18
- display: flex;
19
- flex-direction: column;
20
-
21
- background-color: var(--md-sys-color-surface);
22
- }
23
-
24
- ox-grist {
25
- flex: 1;
26
- }
27
- `
28
- ]
29
-
30
- @property({ type: Array }) quotations: any[] = []
31
- @property({ type: Object }) columns = {
32
- list: { fields: ['name', 'description'] },
33
- pagination: { infinite: true },
34
- columns: [
35
- {
36
- type: 'string',
37
- name: 'name',
38
- header: i18next.t('field.name'),
39
- width: 150
40
- },
41
- {
42
- type: 'string',
43
- name: 'description',
44
- header: i18next.t('field.description'),
45
- width: 200
46
- },
47
- {
48
- type: 'checkbox',
49
- name: 'active',
50
- header: i18next.t('field.active'),
51
- width: 60
52
- }
53
- ]
54
- }
55
-
56
- render() {
57
- return html`
58
- <ox-grist
59
- .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
60
- .config=${this.columns}
61
- .data=${{
62
- records: this.quotations
63
- }}
64
- ></ox-grist>
65
-
66
- <div class="footer">
67
- <div filler></div>
68
- <button @click=${this.save.bind(this)} done><md-icon>save</md-icon>${i18next.t('button.save')}</button>
69
- </div>
70
- `
71
- }
72
-
73
- async save() {
74
- const response = await client.mutate({
75
- mutation: gql`
76
- mutation importQuotations($quotations: [QuotationPatch!]!) {
77
- importQuotations(quotations: $quotations)
78
- }
79
- `,
80
- variables: { quotations: this.quotations }
81
- })
82
-
83
- if (response.errors?.length) return
84
-
85
- this.dispatchEvent(new CustomEvent('imported'))
86
- }
87
- }
@@ -1,323 +0,0 @@
1
- import '@operato/data-grist'
2
-
3
- import { CommonButtonStyles, CommonHeaderStyles, CommonGristStyles, ScrollbarStyles } from '@operato/styles'
4
- import { PageView, store } from '@operato/shell'
5
- import { css, html } from 'lit'
6
- import { customElement, property, query } from 'lit/decorators.js'
7
- import { ScopedElementsMixin } from '@open-wc/scoped-elements'
8
- import { ColumnConfig, DataGrist, FetchOption } from '@operato/data-grist'
9
- import { client } from '@operato/graphql'
10
- import { i18next, localize } from '@operato/i18n'
11
- import { notify, openPopup } from '@operato/layout'
12
- import { isMobileDevice } from '@operato/utils'
13
-
14
- import { connect } from 'pwa-helpers/connect-mixin'
15
- import gql from 'graphql-tag'
16
-
17
- import { QuotationImporter } from './quotation-importer'
18
-
19
- @customElement('quotation-list-page')
20
- export class QuotationListPage extends connect(store)(localize(i18next)(ScopedElementsMixin(PageView))) {
21
- static styles = [
22
- ScrollbarStyles,
23
- CommonGristStyles,
24
- CommonHeaderStyles,
25
- css`
26
- :host {
27
- display: flex;
28
-
29
- width: 100%;
30
-
31
- --grid-record-emphasized-background-color: #8b0000;
32
- --grid-record-emphasized-color: #ff6b6b;
33
- }
34
-
35
- ox-grist {
36
- overflow-y: auto;
37
- flex: 1;
38
- }
39
-
40
- ox-filters-form {
41
- flex: 1;
42
- }
43
- `
44
- ]
45
-
46
- static get scopedElements() {
47
- return {
48
- 'quotation-importer': QuotationImporter
49
- }
50
- }
51
-
52
- @property({ type: Object }) gristConfig: any
53
- @property({ type: String }) mode: 'CARD' | 'GRID' | 'LIST' = isMobileDevice() ? 'CARD' : 'GRID'
54
-
55
- @query('ox-grist') private grist!: DataGrist
56
-
57
- get context() {
58
- return {
59
- title: i18next.t('title.quotation list'),
60
- search: {
61
- handler: (search: string) => {
62
- this.grist.searchText = search
63
- },
64
- value: this.grist?.searchText || ''
65
- },
66
- filter: {
67
- handler: () => {
68
- this.grist.toggleHeadroom()
69
- }
70
- },
71
- help: 'quotation/quotation',
72
- actions: [
73
- {
74
- title: i18next.t('button.save'),
75
- action: this._updateQuotation.bind(this),
76
- ...CommonButtonStyles.save
77
- },
78
- {
79
- title: i18next.t('button.delete'),
80
- action: this._deleteQuotation.bind(this),
81
- ...CommonButtonStyles.delete
82
- }
83
- ],
84
- exportable: {
85
- name: i18next.t('title.quotation list'),
86
- data: this.exportHandler.bind(this)
87
- },
88
- importable: {
89
- handler: this.importHandler.bind(this)
90
- }
91
- }
92
- }
93
-
94
- render() {
95
- const mode = this.mode || (isMobileDevice() ? 'CARD' : 'GRID')
96
-
97
- return html`
98
- <ox-grist .mode=${mode} .config=${this.gristConfig} .fetchHandler=${this.fetchHandler.bind(this)}>
99
- <div slot="headroom" class="header">
100
- <div class="filters">
101
- <ox-filters-form autofocus></ox-filters-form>
102
-
103
- <div id="modes">
104
- <md-icon @click=${() => (this.mode = 'GRID')} ?active=${mode == 'GRID'}>grid_on</md-icon>
105
- <md-icon @click=${() => (this.mode = 'LIST')} ?active=${mode == 'LIST'}>format_list_bulleted</md-icon>
106
- <md-icon @click=${() => (this.mode = 'CARD')} ?active=${mode == 'CARD'}>apps</md-icon>
107
- </div>
108
- </div>
109
- </div>
110
- </ox-grist>
111
- `
112
- }
113
-
114
- async pageInitialized(lifecycle: any) {
115
- this.gristConfig = {
116
- list: {
117
- fields: ['name', 'description'],
118
- details: ['active', 'updatedAt']
119
- },
120
- columns: [
121
- { type: 'gutter', gutterName: 'sequence' },
122
- { type: 'gutter', gutterName: 'row-selector', multiple: true },
123
- {
124
- type: 'string',
125
- name: 'name',
126
- header: i18next.t('field.name'),
127
- record: {
128
- editable: true
129
- },
130
- filter: 'search',
131
- sortable: true,
132
- width: 150
133
- },
134
- {
135
- type: 'string',
136
- name: 'description',
137
- header: i18next.t('field.description'),
138
- record: {
139
- editable: true
140
- },
141
- filter: 'search',
142
- width: 200
143
- },
144
- {
145
- type: 'checkbox',
146
- name: 'active',
147
- label: true,
148
- header: i18next.t('field.active'),
149
- record: {
150
- editable: true
151
- },
152
- filter: true,
153
- sortable: true,
154
- width: 60
155
- },
156
- {
157
- type: 'resource-object',
158
- name: 'updater',
159
- header: i18next.t('field.updater'),
160
- record: {
161
- editable: false
162
- },
163
- sortable: true,
164
- width: 120
165
- },
166
- {
167
- type: 'datetime',
168
- name: 'updatedAt',
169
- header: i18next.t('field.updated_at'),
170
- record: {
171
- editable: false
172
- },
173
- sortable: true,
174
- width: 180
175
- }
176
- ],
177
- rows: {
178
- selectable: {
179
- multiple: true
180
- }
181
- },
182
- sorters: [
183
- {
184
- name: 'name'
185
- }
186
- ]
187
- }
188
- }
189
-
190
- async pageUpdated(changes: any, lifecycle: any) {
191
- if (this.active) {
192
- // do something here when this page just became as active
193
- }
194
- }
195
-
196
- async fetchHandler({ page = 1, limit = 100, sortings = [], filters = [] }: FetchOption) {
197
- const response = await client.query({
198
- query: gql`
199
- query ($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
200
- responses: quotations(filters: $filters, pagination: $pagination, sortings: $sortings) {
201
- items {
202
- id
203
- name
204
- description
205
- active
206
- updater {
207
- id
208
- name
209
- }
210
- updatedAt
211
- }
212
- total
213
- }
214
- }
215
- `,
216
- variables: {
217
- filters,
218
- pagination: { page, limit },
219
- sortings
220
- }
221
- })
222
-
223
- return {
224
- total: response.data.responses.total || 0,
225
- records: response.data.responses.items || []
226
- }
227
- }
228
-
229
- async _deleteQuotation() {
230
- if (confirm(i18next.t('text.sure_to_x', { x: i18next.t('text.delete') }))) {
231
- const ids = this.grist.selected.map(record => record.id)
232
- if (ids && ids.length > 0) {
233
- const response = await client.mutate({
234
- mutation: gql`
235
- mutation ($ids: [String!]!) {
236
- deleteQuotations(ids: $ids)
237
- }
238
- `,
239
- variables: {
240
- ids
241
- }
242
- })
243
-
244
- if (!response.errors) {
245
- this.grist.fetch()
246
- notify({
247
- message: i18next.t('text.info_x_successfully', { x: i18next.t('text.delete') })
248
- })
249
- }
250
- }
251
- }
252
- }
253
-
254
- async _updateQuotation() {
255
- let patches = this.grist.dirtyRecords
256
- if (patches && patches.length) {
257
- patches = patches.map(patch => {
258
- let patchField: any = patch.id ? { id: patch.id } : {}
259
- const dirtyFields = patch.__dirtyfields__
260
- for (let key in dirtyFields) {
261
- patchField[key] = dirtyFields[key].after
262
- }
263
- patchField.cuFlag = patch.__dirty__
264
-
265
- return patchField
266
- })
267
-
268
- const response = await client.mutate({
269
- mutation: gql`
270
- mutation ($patches: [QuotationPatch!]!) {
271
- updateMultipleQuotation(patches: $patches) {
272
- name
273
- }
274
- }
275
- `,
276
- variables: {
277
- patches
278
- }
279
- })
280
-
281
- if (!response.errors) {
282
- this.grist.fetch()
283
- }
284
- }
285
- }
286
-
287
- async exportHandler() {
288
- const exportTargets = this.grist.selected.length ? this.grist.selected : this.grist.dirtyData.records
289
- const targetFieldSet = new Set(['id', 'name', 'description', 'active'])
290
-
291
- return exportTargets.map(quotation => {
292
- let tempObj = {}
293
- for (const field of targetFieldSet) {
294
- tempObj[field] = quotation[field]
295
- }
296
-
297
- return tempObj
298
- })
299
- }
300
-
301
- async importHandler(records) {
302
- const popup = openPopup(
303
- html`
304
- <quotation-importer
305
- .quotations=${records}
306
- @imported=${() => {
307
- history.back()
308
- this.grist.fetch()
309
- }}
310
- ></quotation-importer>
311
- `,
312
- {
313
- backdrop: true,
314
- size: 'large',
315
- title: i18next.t('title.import quotation')
316
- }
317
- )
318
-
319
- popup.onclosed = () => {
320
- this.grist.fetch()
321
- }
322
- }
323
- }
@@ -1,17 +0,0 @@
1
- import { UPDATE_QUOTATION } from '../actions/main'
2
-
3
- const INITIAL_STATE = {
4
- quotation: 'ABC'
5
- }
6
-
7
- const quotation = (state = INITIAL_STATE, action) => {
8
- switch (action.type) {
9
- case UPDATE_QUOTATION:
10
- return { ...state }
11
-
12
- default:
13
- return state
14
- }
15
- }
16
-
17
- export default quotation
package/client/route.ts DELETED
@@ -1,11 +0,0 @@
1
- export default function route(page: string) {
2
- switch (page) {
3
- case 'quotation-main':
4
- import('./pages/main')
5
- return page
6
-
7
- case 'quotation-list':
8
- import('./pages/quotation/quotation-list-page')
9
- return page
10
- }
11
- }
@@ -1,13 +0,0 @@
1
- {
2
- "extends": "../../tsconfig-base.json",
3
- "compilerOptions": {
4
- "experimentalDecorators": true,
5
- "skipLibCheck": true,
6
- "strict": true,
7
- "declaration": true,
8
- "module": "esnext",
9
- "outDir": "../dist-client",
10
- "baseUrl": "./"
11
- },
12
- "include": ["./**/*"]
13
- }