frappe-ui 0.0.43 → 0.0.46
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 +11 -2
- package/src/components/Autocomplete.vue +34 -35
- package/src/components/Dialog.vue +6 -2
- package/src/components/FeatherIcon.vue +1 -1
- package/src/components/Popover.vue +5 -1
- package/src/components/TextEditor/Menu.vue +56 -0
- package/src/components/TextEditor/TextEditor.vue +6 -6
- package/src/components/TextEditor/commands.js +6 -0
- package/src/components/TextEditor/icons/image-add-line.vue +14 -0
- package/src/components/Tooltip.vue +35 -0
- package/src/index.js +1 -0
- package/src/utils/plugin.js +2 -2
- package/src/utils/resources.js +22 -11
- package/src/utils/socketio.js +5 -7
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frappe-ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.46",
|
|
4
4
|
"description": "A set of components and utilities for rapid UI development",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "npx prettier --check ./src",
|
|
8
|
-
"prettier": "npx prettier -w ./src"
|
|
8
|
+
"prettier": "npx prettier -w ./src",
|
|
9
|
+
"prepare": "husky install"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"src"
|
|
@@ -32,5 +33,13 @@
|
|
|
32
33
|
"postcss": "^8.4.5",
|
|
33
34
|
"socket.io-client": "^4.5.1",
|
|
34
35
|
"tailwindcss": "^3.0.12"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"husky": ">=6",
|
|
39
|
+
"lint-staged": ">=10",
|
|
40
|
+
"prettier": "2.7.1"
|
|
41
|
+
},
|
|
42
|
+
"lint-staged": {
|
|
43
|
+
"*.{js,css,md,vue}": "prettier --write"
|
|
35
44
|
}
|
|
36
45
|
}
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<Combobox v-model="selectedValue" nullable>
|
|
2
|
+
<Combobox v-model="selectedValue" nullable v-slot="{ open: isComboboxOpen }">
|
|
3
3
|
<Popover class="w-full">
|
|
4
4
|
<template #target="{ open: openPopover }">
|
|
5
|
-
<div class="
|
|
6
|
-
<
|
|
7
|
-
|
|
8
|
-
class="
|
|
9
|
-
|
|
10
|
-
@change="
|
|
11
|
-
(e) => {
|
|
12
|
-
query = e.target.value
|
|
13
|
-
openPopover()
|
|
14
|
-
}
|
|
15
|
-
"
|
|
16
|
-
@focus="
|
|
5
|
+
<div class="w-full">
|
|
6
|
+
<ComboboxButton
|
|
7
|
+
class="flex items-center justify-between w-full py-1.5 pl-3 pr-2 rounded-md bg-gray-100"
|
|
8
|
+
:class="{ 'rounded-b-none': isComboboxOpen }"
|
|
9
|
+
@click="
|
|
17
10
|
() => {
|
|
18
11
|
openPopover()
|
|
19
|
-
toggleCombobox(true)
|
|
20
12
|
}
|
|
21
13
|
"
|
|
22
|
-
@keydown="toggleCombobox(true)"
|
|
23
|
-
autocomplete="off"
|
|
24
|
-
v-bind="$attrs"
|
|
25
|
-
/>
|
|
26
|
-
<ComboboxButton
|
|
27
|
-
class="absolute inset-y-0 right-0 flex items-center pr-2"
|
|
28
14
|
>
|
|
15
|
+
<span class="text-base" v-if="selectedValue">
|
|
16
|
+
{{ displayValue(selectedValue) }}
|
|
17
|
+
</span>
|
|
18
|
+
<span class="text-base text-gray-500" v-else>
|
|
19
|
+
{{ placeholder || '' }}
|
|
20
|
+
</span>
|
|
29
21
|
<FeatherIcon
|
|
30
22
|
name="chevron-down"
|
|
31
23
|
class="w-4 h-4 text-gray-500"
|
|
@@ -36,12 +28,27 @@
|
|
|
36
28
|
</template>
|
|
37
29
|
<template #body>
|
|
38
30
|
<ComboboxOptions
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
]"
|
|
43
|
-
:static="true"
|
|
31
|
+
class="px-1.5 pb-1.5 bg-white rounded-md shadow-md rounded-t-none max-h-[11rem] overflow-y-auto"
|
|
32
|
+
static
|
|
33
|
+
v-show="isComboboxOpen"
|
|
44
34
|
>
|
|
35
|
+
<div
|
|
36
|
+
class="flex items-st items-stretch space-x-1.5 sticky top-0 pt-1.5 mb-1.5 bg-white"
|
|
37
|
+
>
|
|
38
|
+
<ComboboxInput
|
|
39
|
+
class="w-full placeholder-gray-500 form-input"
|
|
40
|
+
type="text"
|
|
41
|
+
@change="
|
|
42
|
+
(e) => {
|
|
43
|
+
query = e.target.value
|
|
44
|
+
}
|
|
45
|
+
"
|
|
46
|
+
:value="query"
|
|
47
|
+
autocomplete="off"
|
|
48
|
+
placeholder="Search by keyword"
|
|
49
|
+
/>
|
|
50
|
+
<Button icon="x" @click="selectedValue = null" />
|
|
51
|
+
</div>
|
|
45
52
|
<ComboboxOption
|
|
46
53
|
as="template"
|
|
47
54
|
v-for="option in filteredOptions"
|
|
@@ -81,8 +88,7 @@ import Popover from './Popover.vue'
|
|
|
81
88
|
|
|
82
89
|
export default {
|
|
83
90
|
name: 'Autocomplete',
|
|
84
|
-
|
|
85
|
-
props: ['modelValue', 'options'],
|
|
91
|
+
props: ['modelValue', 'options', 'placeholder'],
|
|
86
92
|
emits: ['update:modelValue', 'change'],
|
|
87
93
|
components: {
|
|
88
94
|
Popover,
|
|
@@ -94,7 +100,6 @@ export default {
|
|
|
94
100
|
},
|
|
95
101
|
data() {
|
|
96
102
|
return {
|
|
97
|
-
showCombobox: false,
|
|
98
103
|
query: '',
|
|
99
104
|
}
|
|
100
105
|
},
|
|
@@ -107,7 +112,7 @@ export default {
|
|
|
107
112
|
return this.valuePropPassed ? this.$attrs.value : this.modelValue
|
|
108
113
|
},
|
|
109
114
|
set(val) {
|
|
110
|
-
|
|
115
|
+
this.query = ''
|
|
111
116
|
this.$emit(this.valuePropPassed ? 'change' : 'update:modelValue', val)
|
|
112
117
|
},
|
|
113
118
|
},
|
|
@@ -130,12 +135,6 @@ export default {
|
|
|
130
135
|
}
|
|
131
136
|
return option?.label
|
|
132
137
|
},
|
|
133
|
-
toggleCombobox(value) {
|
|
134
|
-
value = Boolean(value)
|
|
135
|
-
if (this.showCombobox !== value) {
|
|
136
|
-
this.showCombobox = value
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
138
|
},
|
|
140
139
|
}
|
|
141
140
|
</script>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TransitionRoot
|
|
2
|
+
<TransitionRoot
|
|
3
|
+
as="template"
|
|
4
|
+
:show="open"
|
|
5
|
+
@after-leave="$emit('after-leave')"
|
|
6
|
+
>
|
|
3
7
|
<HDialog
|
|
4
8
|
as="div"
|
|
5
9
|
class="fixed inset-0 z-10 overflow-y-auto"
|
|
@@ -137,7 +141,7 @@ export default {
|
|
|
137
141
|
},
|
|
138
142
|
},
|
|
139
143
|
},
|
|
140
|
-
emits: ['update:modelValue', 'close'],
|
|
144
|
+
emits: ['update:modelValue', 'close', 'after-leave'],
|
|
141
145
|
components: {
|
|
142
146
|
HDialog,
|
|
143
147
|
DialogOverlay,
|
|
@@ -208,10 +208,13 @@ export default {
|
|
|
208
208
|
this.isOpen = false
|
|
209
209
|
},
|
|
210
210
|
onMouseover() {
|
|
211
|
+
this.mouseover = true
|
|
211
212
|
if (this.trigger === 'hover') {
|
|
212
213
|
if (this.hoverDelay) {
|
|
213
214
|
this.hoverTimer = setTimeout(() => {
|
|
214
|
-
this.
|
|
215
|
+
if (this.mouseover) {
|
|
216
|
+
this.open()
|
|
217
|
+
}
|
|
215
218
|
}, Number(this.hoverDelay) * 1000)
|
|
216
219
|
} else {
|
|
217
220
|
this.open()
|
|
@@ -219,6 +222,7 @@ export default {
|
|
|
219
222
|
}
|
|
220
223
|
},
|
|
221
224
|
onMouseleave() {
|
|
225
|
+
this.mouseover = false
|
|
222
226
|
if (this.hoverTimer) {
|
|
223
227
|
clearTimeout(this.hoverTimer)
|
|
224
228
|
}
|
|
@@ -67,6 +67,39 @@
|
|
|
67
67
|
</Button>
|
|
68
68
|
</template>
|
|
69
69
|
</Dialog>
|
|
70
|
+
<Dialog
|
|
71
|
+
:options="{ title: 'Add Image' }"
|
|
72
|
+
v-model="addImageDialog.show"
|
|
73
|
+
@after-leave="resetAddImage"
|
|
74
|
+
>
|
|
75
|
+
<template #body-content>
|
|
76
|
+
<label
|
|
77
|
+
class="relative py-1 bg-gray-100 rounded-lg cursor-pointer focus-within:bg-gray-200 hover:bg-gray-200"
|
|
78
|
+
>
|
|
79
|
+
<input
|
|
80
|
+
type="file"
|
|
81
|
+
class="w-full opacity-0"
|
|
82
|
+
@change="onImageSelect"
|
|
83
|
+
accept="image/*"
|
|
84
|
+
/>
|
|
85
|
+
<span class="absolute inset-0 px-2 py-1 text-base select-none">
|
|
86
|
+
{{
|
|
87
|
+
addImageDialog.file ? 'Select another image' : 'Select an image'
|
|
88
|
+
}}
|
|
89
|
+
</span>
|
|
90
|
+
</label>
|
|
91
|
+
<img
|
|
92
|
+
v-if="addImageDialog.url"
|
|
93
|
+
:src="addImageDialog.url"
|
|
94
|
+
class="w-full mt-2 rounded-lg"
|
|
95
|
+
/>
|
|
96
|
+
</template>
|
|
97
|
+
<template #actions>
|
|
98
|
+
<Button appearance="primary" @click="addImage(addImageDialog.url)">
|
|
99
|
+
Insert Image
|
|
100
|
+
</Button>
|
|
101
|
+
</template>
|
|
102
|
+
</Dialog>
|
|
70
103
|
</div>
|
|
71
104
|
</template>
|
|
72
105
|
<script>
|
|
@@ -83,6 +116,7 @@ export default {
|
|
|
83
116
|
data() {
|
|
84
117
|
return {
|
|
85
118
|
setLinkDialog: { url: '', show: false },
|
|
119
|
+
addImageDialog: { url: '', file: null, show: false },
|
|
86
120
|
}
|
|
87
121
|
},
|
|
88
122
|
methods: {
|
|
@@ -93,6 +127,8 @@ export default {
|
|
|
93
127
|
if (existingURL) {
|
|
94
128
|
this.setLinkDialog.url = existingURL
|
|
95
129
|
}
|
|
130
|
+
} else if (button.label === 'Image') {
|
|
131
|
+
this.addImageDialog.show = true
|
|
96
132
|
} else {
|
|
97
133
|
button.action(this.editor)
|
|
98
134
|
}
|
|
@@ -114,6 +150,26 @@ export default {
|
|
|
114
150
|
this.setLinkDialog.show = false
|
|
115
151
|
this.setLinkDialog.url = ''
|
|
116
152
|
},
|
|
153
|
+
onImageSelect(e) {
|
|
154
|
+
let file = e.target.files[0]
|
|
155
|
+
if (!file) {
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
this.addImageDialog.file = file
|
|
159
|
+
let reader = new FileReader()
|
|
160
|
+
reader.onloadend = () => {
|
|
161
|
+
let base64string = reader.result
|
|
162
|
+
this.addImageDialog.url = base64string
|
|
163
|
+
}
|
|
164
|
+
reader.readAsDataURL(file)
|
|
165
|
+
},
|
|
166
|
+
addImage(src) {
|
|
167
|
+
this.editor.chain().focus().setImage({ src }).run()
|
|
168
|
+
this.resetAddImage()
|
|
169
|
+
},
|
|
170
|
+
resetAddImage() {
|
|
171
|
+
this.addImageDialog = { show: false, url: null, file: null }
|
|
172
|
+
},
|
|
117
173
|
},
|
|
118
174
|
}
|
|
119
175
|
</script>
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
<editor-content :editor="editor" />
|
|
44
44
|
<span
|
|
45
45
|
v-if="!content"
|
|
46
|
-
class="absolute
|
|
46
|
+
class="absolute top-0 text-base text-gray-500 pointer-events-none"
|
|
47
47
|
>
|
|
48
48
|
{{ placeholder }}
|
|
49
49
|
</span>
|
|
@@ -119,7 +119,9 @@ export default {
|
|
|
119
119
|
TextAlign.configure({
|
|
120
120
|
types: ['heading', 'paragraph'],
|
|
121
121
|
}),
|
|
122
|
-
Image
|
|
122
|
+
Image.configure({
|
|
123
|
+
allowBase64: true,
|
|
124
|
+
}),
|
|
123
125
|
Link,
|
|
124
126
|
Placeholder.configure({
|
|
125
127
|
placeholder: this.placeholder || 'Write something...',
|
|
@@ -163,6 +165,7 @@ export default {
|
|
|
163
165
|
'Align Center',
|
|
164
166
|
'Align Right',
|
|
165
167
|
'Separator',
|
|
168
|
+
'Image',
|
|
166
169
|
'Blockquote',
|
|
167
170
|
'Code',
|
|
168
171
|
'Horizontal Rule',
|
|
@@ -220,10 +223,7 @@ export default {
|
|
|
220
223
|
editorProps() {
|
|
221
224
|
return {
|
|
222
225
|
attributes: {
|
|
223
|
-
class: normalizeClass([
|
|
224
|
-
'prose prose-sm prose-p:my-1',
|
|
225
|
-
this.editorClass,
|
|
226
|
-
]),
|
|
226
|
+
class: normalizeClass(['prose prose-p:my-1', this.editorClass]),
|
|
227
227
|
},
|
|
228
228
|
}
|
|
229
229
|
},
|
|
@@ -16,6 +16,7 @@ import ListUnordered from './icons/list-unordered.vue'
|
|
|
16
16
|
import DoubleQuotes from './icons/double-quotes-r.vue'
|
|
17
17
|
import CodeView from './icons/code-view.vue'
|
|
18
18
|
import Link from './icons/link.vue'
|
|
19
|
+
import Image from './icons/image-add-line.vue'
|
|
19
20
|
import ArrowGoBack from './icons/arrow-go-back-line.vue'
|
|
20
21
|
import ArrowGoForward from './icons/arrow-go-forward-line.vue'
|
|
21
22
|
import Separator from './icons/separator.vue'
|
|
@@ -146,6 +147,11 @@ export default {
|
|
|
146
147
|
icon: Link,
|
|
147
148
|
isActive: (editor) => editor.isActive('link'),
|
|
148
149
|
},
|
|
150
|
+
Image: {
|
|
151
|
+
label: 'Image',
|
|
152
|
+
icon: Image,
|
|
153
|
+
isActive: (editor) => false,
|
|
154
|
+
},
|
|
149
155
|
Undo: {
|
|
150
156
|
label: 'Undo',
|
|
151
157
|
icon: ArrowGoBack,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<svg
|
|
3
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
4
|
+
viewBox="0 0 24 24"
|
|
5
|
+
width="24"
|
|
6
|
+
height="24"
|
|
7
|
+
>
|
|
8
|
+
<path fill="none" d="M0 0h24v24H0z" />
|
|
9
|
+
<path
|
|
10
|
+
d="M21 15v3h3v2h-3v3h-2v-3h-3v-2h3v-3h2zm.008-12c.548 0 .992.445.992.993V13h-2V5H4v13.999L14 9l3 3v2.829l-3-3L6.827 19H14v2H2.992A.993.993 0 0 1 2 20.007V3.993A1 1 0 0 1 2.992 3h18.016zM8 7a2 2 0 1 1 0 4 2 2 0 0 1 0-4z"
|
|
11
|
+
fill="currentColor"
|
|
12
|
+
/>
|
|
13
|
+
</svg>
|
|
14
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<Popover trigger="hover" :hoverDelay="hoverDelay" :placement="placement">
|
|
3
|
+
<template #target>
|
|
4
|
+
<slot />
|
|
5
|
+
</template>
|
|
6
|
+
<template #body>
|
|
7
|
+
<slot name="body">
|
|
8
|
+
<div
|
|
9
|
+
class="px-2 py-1 text-xs text-white bg-gray-800 border border-gray-100 rounded-lg shadow-xl"
|
|
10
|
+
>
|
|
11
|
+
{{ text }}
|
|
12
|
+
</div>
|
|
13
|
+
</slot>
|
|
14
|
+
</template>
|
|
15
|
+
</Popover>
|
|
16
|
+
</template>
|
|
17
|
+
<script>
|
|
18
|
+
import Popover from './Popover.vue'
|
|
19
|
+
export default {
|
|
20
|
+
name: 'Tooltip',
|
|
21
|
+
components: { Popover },
|
|
22
|
+
props: {
|
|
23
|
+
hoverDelay: {
|
|
24
|
+
default: 0.5,
|
|
25
|
+
},
|
|
26
|
+
placement: {
|
|
27
|
+
default: 'bottom-start',
|
|
28
|
+
},
|
|
29
|
+
text: {
|
|
30
|
+
type: String,
|
|
31
|
+
default: '',
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
</script>
|
package/src/index.js
CHANGED
|
@@ -23,6 +23,7 @@ export { default as Resource } from './components/Resource.vue'
|
|
|
23
23
|
export { default as Spinner } from './components/Spinner.vue'
|
|
24
24
|
export { default as SuccessMessage } from './components/SuccessMessage.vue'
|
|
25
25
|
export { default as TextEditor } from './components/TextEditor'
|
|
26
|
+
export { default as Tooltip } from './components/Tooltip.vue'
|
|
26
27
|
|
|
27
28
|
// directives
|
|
28
29
|
export { default as onOutsideClickDirective } from './directives/onOutsideClick.js'
|
package/src/utils/plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import resources from './resources'
|
|
2
2
|
import call from './call'
|
|
3
|
-
import
|
|
3
|
+
import initSocket from './socketio'
|
|
4
4
|
|
|
5
5
|
let defaultOptions = {
|
|
6
6
|
resources: true,
|
|
@@ -18,7 +18,7 @@ export default {
|
|
|
18
18
|
app.config.globalProperties.$call = callFunction
|
|
19
19
|
}
|
|
20
20
|
if (options.socketio) {
|
|
21
|
-
app.config.globalProperties.$socket =
|
|
21
|
+
app.config.globalProperties.$socket = initSocket(options.socketio)
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
}
|
package/src/utils/resources.js
CHANGED
|
@@ -201,6 +201,7 @@ export function createDocumentResource(options, vm) {
|
|
|
201
201
|
doctype: options.doctype,
|
|
202
202
|
name: options.name,
|
|
203
203
|
doc: null,
|
|
204
|
+
auto: true,
|
|
204
205
|
get: createResource(
|
|
205
206
|
{
|
|
206
207
|
method: 'frappe.client.get',
|
|
@@ -212,6 +213,7 @@ export function createDocumentResource(options, vm) {
|
|
|
212
213
|
},
|
|
213
214
|
onSuccess(data) {
|
|
214
215
|
out.doc = transform(data)
|
|
216
|
+
options.onSuccess?.call(vm, out.doc)
|
|
215
217
|
},
|
|
216
218
|
onError: options.onError,
|
|
217
219
|
},
|
|
@@ -237,6 +239,8 @@ export function createDocumentResource(options, vm) {
|
|
|
237
239
|
onSuccess() {
|
|
238
240
|
out.doc = null
|
|
239
241
|
options.delete?.onSuccess?.call(vm, data)
|
|
242
|
+
// delete from list resources
|
|
243
|
+
deleteRowInListResource(out.doctype, out.name)
|
|
240
244
|
},
|
|
241
245
|
onError: options.delete?.onError,
|
|
242
246
|
},
|
|
@@ -294,8 +298,6 @@ export function createDocumentResource(options, vm) {
|
|
|
294
298
|
return doc
|
|
295
299
|
}
|
|
296
300
|
|
|
297
|
-
// fetch the doc
|
|
298
|
-
out.get.fetch()
|
|
299
301
|
// cache
|
|
300
302
|
documentCache[cacheKey] = out
|
|
301
303
|
return out
|
|
@@ -322,6 +324,7 @@ export function createListResource(options, vm, getResource) {
|
|
|
322
324
|
data: null,
|
|
323
325
|
next,
|
|
324
326
|
hasNextPage: true,
|
|
327
|
+
auto: true,
|
|
325
328
|
list: createResource(
|
|
326
329
|
{
|
|
327
330
|
method: 'frappe.client.get_list',
|
|
@@ -450,7 +453,6 @@ export function createListResource(options, vm, getResource) {
|
|
|
450
453
|
out.order_by = updatedOptions.order_by
|
|
451
454
|
out.start = updatedOptions.start
|
|
452
455
|
out.limit = updatedOptions.limit
|
|
453
|
-
out.list.fetch()
|
|
454
456
|
}
|
|
455
457
|
|
|
456
458
|
function transform(data) {
|
|
@@ -480,9 +482,6 @@ export function createListResource(options, vm, getResource) {
|
|
|
480
482
|
out.list.fetch()
|
|
481
483
|
}
|
|
482
484
|
|
|
483
|
-
// fetch list
|
|
484
|
-
out.list.fetch()
|
|
485
|
-
|
|
486
485
|
if (cacheKey) {
|
|
487
486
|
// cache
|
|
488
487
|
listCache[cacheKey] = out
|
|
@@ -495,7 +494,7 @@ export function createListResource(options, vm, getResource) {
|
|
|
495
494
|
}
|
|
496
495
|
|
|
497
496
|
function updateRowInListResource(doctype, doc) {
|
|
498
|
-
let resources = listResources[doctype]
|
|
497
|
+
let resources = listResources[doctype] || []
|
|
499
498
|
for (let resource of resources) {
|
|
500
499
|
if (resource.originalData) {
|
|
501
500
|
for (let row of resource.originalData) {
|
|
@@ -514,8 +513,20 @@ function updateRowInListResource(doctype, doc) {
|
|
|
514
513
|
}
|
|
515
514
|
}
|
|
516
515
|
|
|
516
|
+
function deleteRowInListResource(doctype, docname) {
|
|
517
|
+
let resources = listResources[doctype] || []
|
|
518
|
+
for (let resource of resources) {
|
|
519
|
+
if (resource.originalData) {
|
|
520
|
+
resource.originalData = resource.originalData.filter(
|
|
521
|
+
(row) => row.name !== docname
|
|
522
|
+
)
|
|
523
|
+
resource.data = resource.transform(resource.originalData)
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
517
528
|
function revertRowInListResource(doctype, doc) {
|
|
518
|
-
let resources = listResources[doctype]
|
|
529
|
+
let resources = listResources[doctype] || []
|
|
519
530
|
for (let resource of resources) {
|
|
520
531
|
if (resource.originalData) {
|
|
521
532
|
for (let row of resource.originalData) {
|
|
@@ -592,7 +603,7 @@ let createMixin = (mixinOptions) => ({
|
|
|
592
603
|
resource.update(updatedOptions)
|
|
593
604
|
}
|
|
594
605
|
if (resource && resource.auto) {
|
|
595
|
-
resource.
|
|
606
|
+
resource.reload()
|
|
596
607
|
}
|
|
597
608
|
},
|
|
598
609
|
{
|
|
@@ -606,8 +617,8 @@ let createMixin = (mixinOptions) => ({
|
|
|
606
617
|
mixinOptions.getResource
|
|
607
618
|
)
|
|
608
619
|
this._resources[key] = resource
|
|
609
|
-
if (resource.auto) {
|
|
610
|
-
resource.
|
|
620
|
+
if (resource && resource.auto) {
|
|
621
|
+
resource.reload()
|
|
611
622
|
}
|
|
612
623
|
}
|
|
613
624
|
}
|
package/src/utils/socketio.js
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { io } from 'socket.io-client'
|
|
2
2
|
|
|
3
|
-
function initSocket() {
|
|
3
|
+
export default function initSocket(options = {}) {
|
|
4
4
|
let host = window.location.hostname
|
|
5
|
-
let
|
|
5
|
+
let socketio_port = options.port || 9000
|
|
6
|
+
let port = window.location.port ? `:${socketio_port}` : ''
|
|
6
7
|
let protocol = port ? 'http' : 'https'
|
|
7
8
|
let url = `${protocol}://${host}${port}`
|
|
8
|
-
|
|
9
|
+
let socket = io(url)
|
|
10
|
+
return socket
|
|
9
11
|
}
|
|
10
|
-
|
|
11
|
-
let socket = initSocket()
|
|
12
|
-
|
|
13
|
-
export default socket
|