From afc341901e41ae64da797585feeef60357d122f4 Mon Sep 17 00:00:00 2001 From: osdodo Date: Mon, 22 May 2023 12:10:02 +0800 Subject: [PATCH 1/4] create a default device --- src/components/IDE/EventLogs/index.tsx | 53 ++++++++++---------------- src/lib/hooks.ts | 25 ++++++++++++ 2 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/components/IDE/EventLogs/index.tsx b/src/components/IDE/EventLogs/index.tsx index 5e723d4a..8efde18f 100644 --- a/src/components/IDE/EventLogs/index.tsx +++ b/src/components/IDE/EventLogs/index.tsx @@ -197,39 +197,28 @@ const EventLogs = observer(() => { }} onClick={async () => { publisher.developerPublishEventForm.afterSubmit = async ({ formData }) => { - const projectName = curProject?.f_name; - if (projectName) { - const pub = publisher.allData.find((item) => item.project_id === curProject?.f_project_id); - if (!pub) { - showNotification({ color: 'red', message: 'Please create a publisher first' }); - eventBus.emit('base.formModal.abort'); - setTimeout(() => { - w3s.showContent = 'CURRENT_PUBLISHERS'; - }, 2000); - return; - } - publisher.records.push({ - type: formData.type, - body: formData.body + publisher.records.push({ + type: formData.type, + body: formData.body + }); + try { + const token = await hooks.waitPublisher(); + await axios.request({ + method: 'post', + url: `/api/w3bapp/event/${curProject?.f_nam}`, + headers: { + Authorization: token, + 'Content-Type': 'application/octet-stream' + }, + params: { + eventType: formData.type || 'DEFAULT', + timestamp: Date.now() + }, + data: formData.body }); - try { - const res = await axios.request({ - method: 'post', - url: `/api/w3bapp/event/${projectName}`, - headers: { - Authorization: pub.f_token, - 'Content-Type': 'application/octet-stream' - }, - params: { - eventType: formData.type || 'DEFAULT', - timestamp: Date.now() - }, - data: formData.body - }); - showNotification({ color: 'green', message: 'Send event successed' }); - } catch (error) { - showNotification({ color: 'red', message: 'send event failed' }); - } + showNotification({ color: 'green', message: 'Send event successed' }); + } catch (error) { + showNotification({ color: 'red', message: 'send event failed' }); } }; hooks.getFormData({ diff --git a/src/lib/hooks.ts b/src/lib/hooks.ts index e6e5975f..304b4a34 100644 --- a/src/lib/hooks.ts +++ b/src/lib/hooks.ts @@ -4,6 +4,7 @@ import { eventBus } from './event'; import initSqlJs from 'sql.js'; import { IndexDb } from './dexie'; import { helper } from './helper'; +import { axios } from './axios'; export const hooks = { async waitReady() { @@ -73,5 +74,29 @@ export const hooks = { res(); }, ms); }); + }, + async waitPublisher() { + const allPublisher = rootStore.w3s.publisher.allData; + const curProject = rootStore.w3s.project.curProject; + const pub = allPublisher.find((item) => item.project_id === curProject?.f_project_id); + if (pub) { + return pub.f_token; + } else { + try { + const key = `default`; + const res = await axios.request({ + method: 'post', + url: `/api/w3bapp/publisher/x/${curProject?.name}`, + data: { + key, + name: key + } + }); + eventBus.emit('publisher.create'); + return res.data?.token; + } catch (error) { + return; + } + } } }; From 82576e5889aa90d5ac92f2b5044f9c90e14b362c Mon Sep 17 00:00:00 2001 From: osdodo Date: Mon, 22 May 2023 13:15:42 +0800 Subject: [PATCH 2/4] fix single data display issue --- .../JSONMetricsView/LineChartCard/index.tsx | 5 +++-- src/store/lib/w3bstream/schema/metrics.ts | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/components/JSONMetricsView/LineChartCard/index.tsx b/src/components/JSONMetricsView/LineChartCard/index.tsx index 29aa1675..3dbbbb49 100644 --- a/src/components/JSONMetricsView/LineChartCard/index.tsx +++ b/src/components/JSONMetricsView/LineChartCard/index.tsx @@ -41,10 +41,11 @@ export const LineChartCard = ({ }, yScale = { type: 'linear', - min: 'auto', + min: 0, max: 'auto', stacked: true, - reverse: false + reverse: false, + nice: true, }, axisTop = null, axisRight = null, diff --git a/src/store/lib/w3bstream/schema/metrics.ts b/src/store/lib/w3bstream/schema/metrics.ts index d953264b..b886abfd 100644 --- a/src/store/lib/w3bstream/schema/metrics.ts +++ b/src/store/lib/w3bstream/schema/metrics.ts @@ -116,10 +116,14 @@ export default class MetricsModule { get activeDevicesMetrics(): JSONMetricsView { const values = this.activeDevices.value[0]?.values || []; - const list = values + let list = values .slice() .sort((a, b) => a[0] - b[0]) .map((i) => ({ x: dayjs(i[0] * 1000).format('YYYY-MM-DD HH:mm'), y: Number(i[1]) })); + if (list.length === 1) { + const d = dayjs(list[0][0]); + list = [{ x: d.subtract(8, 'hour').format('YYYY-MM-DD HH:mm'), y: 0 }, { x: d.subtract(4, 'hour').format('YYYY-MM-DD HH:mm'), y: 0 }, ...list]; + } return { type: 'LineChartCard', data: { @@ -150,10 +154,14 @@ export default class MetricsModule { get dataMessagesMetrics(): JSONMetricsView { const values = this.dataMessages.value[0]?.values || []; - const list = values + let list = values .slice() .sort((a, b) => a[0] - b[0]) .map((i) => ({ x: dayjs(i[0] * 1000).format('YYYY-MM-DD HH:mm'), y: Number(i[1]) })); + if (list.length === 1) { + const d = dayjs(list[0][0]); + list = [{ x: d.subtract(8, 'hour').format('YYYY-MM-DD HH:mm'), y: 0 }, { x: d.subtract(4, 'hour').format('YYYY-MM-DD HH:mm'), y: 0 }, ...list]; + } return { type: 'LineChartCard', data: { @@ -184,10 +192,14 @@ export default class MetricsModule { get blockchainTransactionMetrics(): JSONMetricsView { const values = this.blockchainTransaction.value[0]?.values || []; - const list = values + let list = values .slice() .sort((a, b) => a[0] - b[0]) .map((i) => ({ x: dayjs(i[0] * 1000).format('YYYY-MM-DD HH:mm'), y: Number(i[1]) })); + if (list.length === 1) { + const d = dayjs(list[0][0]); + list = [{ x: d.subtract(8, 'hour').format('YYYY-MM-DD HH:mm'), y: 0 }, { x: d.subtract(4, 'hour').format('YYYY-MM-DD HH:mm'), y: 0 }, ...list]; + } return { type: 'LineChartCard', data: { From ccf169665018481475f4abb23360663755cdc4c0 Mon Sep 17 00:00:00 2001 From: osdodo Date: Mon, 22 May 2023 13:21:40 +0800 Subject: [PATCH 3/4] update fetch log limit --- src/components/IDE/EventLogs/index.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/IDE/EventLogs/index.tsx b/src/components/IDE/EventLogs/index.tsx index 8efde18f..8df99966 100644 --- a/src/components/IDE/EventLogs/index.tsx +++ b/src/components/IDE/EventLogs/index.tsx @@ -125,7 +125,6 @@ const poll = (fn: { (): Promise; (): void; }, interval = 3000) => { const EventLogs = observer(() => { const { - w3s, w3s: { publisher, project: { curProject } @@ -306,7 +305,7 @@ const EventLogs = observer(() => { const createdAt = store.logs[0]?.f_created_at; const res = await fetchWasmLogs({ projectName, - limit: 10, + limit: 50, lt: createdAt ? Number(createdAt) : undefined, }); store.setData({ From d56d013e476c3ad78e225a9a3ee67f014501f758 Mon Sep 17 00:00:00 2001 From: osdodo Date: Mon, 22 May 2023 16:09:08 +0800 Subject: [PATCH 4/4] update wasm schema --- .../DeveloperIDE/Projects/index.tsx | 18 +-- .../DeveloperIDE/Settings/index.tsx | 25 ++-- src/store/lib/w3bstream/schema/applet.tsx | 125 +++++++++--------- 3 files changed, 80 insertions(+), 88 deletions(-) diff --git a/src/components/DeveloperIDE/Projects/index.tsx b/src/components/DeveloperIDE/Projects/index.tsx index 433b136c..be5e0d23 100644 --- a/src/components/DeveloperIDE/Projects/index.tsx +++ b/src/components/DeveloperIDE/Projects/index.tsx @@ -145,12 +145,10 @@ const Projects = observer(() => { allProjects.onSelect(index); w3s.showContent = 'METRICS'; } else { - const appletID = await w3s.applet.createAppletForDeveloper({ - projectName: project.name + await w3s.applet.uploadWASM({ + projectName: project.name, + formTitle: 'Upload WASM' }); - if (appletID) { - eventBus.emit('applet.create'); - } } }} > @@ -169,15 +167,13 @@ const Projects = observer(() => { {...defaultButtonStyle} onClick={async (e) => { e.stopPropagation(); - const appletID = await w3s.applet.createAppletForDeveloper({ - projectName: project.name + await w3s.applet.uploadWASM({ + projectName: project.name, + formTitle: 'Upload WASM' }); - if (appletID) { - eventBus.emit('applet.create'); - } }} > - Create instance + Upload WASM )} diff --git a/src/components/DeveloperIDE/Settings/index.tsx b/src/components/DeveloperIDE/Settings/index.tsx index baf79dcc..11b6726c 100644 --- a/src/components/DeveloperIDE/Settings/index.tsx +++ b/src/components/DeveloperIDE/Settings/index.tsx @@ -17,9 +17,6 @@ const Settings = () => { } = useStore(); const store = useLocalObservable(() => ({ - get curApplet() { - return applet.allData.find((item) => item.project_name === project.curProject?.name); - }, get curInstance() { return instances.table.dataSource.find((item) => item.project_name === project.curProject?.name); }, @@ -51,10 +48,10 @@ const Settings = () => { }, []); useEffect(() => { - if (store.curApplet) { - applet.wasmName.call(store.curApplet.f_resource_id); + if (applet.curApplet) { + applet.wasmName.call(applet.curApplet.f_resource_id); } - }, [store.curApplet]); + }, [applet.curApplet]); return ( @@ -113,19 +110,13 @@ const Settings = () => { size="sm" {...defaultOutlineButtonStyle} onClick={async () => { - if (store.curApplet && store.curInstance) { - applet.form.uiSchema.projectName = { - 'ui:widget': 'hidden' - }; - applet.form.uiSchema.appletName = { - 'ui:widget': 'hidden' - }; - applet.form.value.set({ + if (applet.curApplet && store.curInstance) { + await applet.uploadWASM({ projectName: project.curProject?.name, - appletName: store.curApplet.f_name + appletName: applet.curApplet.f_name, + type: 'update', + formTitle: 'Update WASM' }); - await applet.updateWASM(store.curApplet.f_applet_id, store.curApplet.f_name); - applet.wasmName.call(store.curApplet.f_resource_id); } }} > diff --git a/src/store/lib/w3bstream/schema/applet.tsx b/src/store/lib/w3bstream/schema/applet.tsx index 5789c560..cfe4e470 100644 --- a/src/store/lib/w3bstream/schema/applet.tsx +++ b/src/store/lib/w3bstream/schema/applet.tsx @@ -12,7 +12,6 @@ import { showNotification } from '@mantine/notifications'; import { dataURItoBlob, UiSchema } from '@rjsf/utils'; import { FromSchema } from 'json-schema-to-ts'; import { definitions } from './definitions'; -import { helper } from '@/lib/helper'; export const schema = { definitions: { @@ -27,12 +26,12 @@ export const schema = { title: 'Upload Single File' }, projectName: { $ref: '#/definitions/projects', title: 'Project Name' }, - appletName: { type: 'string', title: 'Applet Name' } + appletName: { type: 'string', title: 'Applet Name' }, }, required: ['file', 'projectName', 'appletName'] } as const; -export const developerSchema = { +export const uploadWASMSchema = { definitions: { projects: { type: 'string' @@ -49,7 +48,7 @@ export const developerSchema = { } as const; type SchemaType = FromSchema; -type DeveloperSchemaType = FromSchema; +type UploadWASMSchemaType = FromSchema; //@ts-ignore schema.definitions = { @@ -88,9 +87,9 @@ export default class AppletModule { }) }); - developerForm = new JSONSchemaFormState({ + uploadWASMForm = new JSONSchemaFormState({ //@ts-ignore - schema: developerSchema, + schema: uploadWASMSchema, uiSchema: { 'ui:submitButtonOptions': { norender: false, @@ -108,9 +107,14 @@ export default class AppletModule { }, afterSubmit: async (e) => { eventBus.emit('base.formModal.afterSubmit', e.formData); - this.developerForm.reset(); + this.uploadWASMForm.reset(); }, - value: new JSONValue() + value: new JSONValue({ + //@ts-ignore + default: { + file: '' + } + }) }); table = new JSONSchemaTableState({ @@ -379,8 +383,8 @@ export default class AppletModule { allData: AppletType[] = []; - set(v: Partial) { - Object.assign(this, v); + get curApplet() { + return this.allData.find((item) => item.project_name === globalThis.store.w3s.project.curProject?.name); } wasmName = new PromiseState<(resourceId) => Promise, string>({ @@ -397,6 +401,10 @@ export default class AppletModule { } }); + set(v: Partial) { + Object.assign(this, v); + } + async createApplet() { const formData = await hooks.getFormData({ title: 'Create Applet', @@ -453,18 +461,30 @@ export default class AppletModule { return null; } - async createAppletForDeveloper({ projectName, appletName = 'applet_1' }: { projectName: string; appletName?: string }) { - const formData = await hooks.getFormData({ - title: 'Create instance', - size: 'md', - formList: [ - { - form: this.developerForm - } - ] - }); + async uploadWASM({ projectName, appletName = 'applet_1', type = 'add', formTitle = '' }: { projectName: string; appletName?: string; type?: 'add' | 'update', formTitle?: string }) { + let formData = { + file: '' + }; + + try { + this.uploadWASMForm.reset(); + formData = await hooks.getFormData({ + title: formTitle, + size: '2xl', + formList: [ + { + form: this.uploadWASMForm + } + ] + }); + } catch (error) { + this.uploadWASMForm.reset(); + return; + } + + const data = new FormData(); + if (formData.file) { - const data = new FormData(); const file = dataURItoBlob(formData.file); data.append('file', file.blob); data.append( @@ -476,54 +496,40 @@ export default class AppletModule { start: true }) ); - const res = await axios.request({ - method: 'post', - url: `/api/file?api=applet/x/${projectName}`, - headers: { - 'Content-Type': 'multipart/form-data' - }, - data - }); - const appletID = res.data?.appletID; - if (appletID) { - return appletID; - } - return null; } - } - async updateWASM(appletID, appletName) { - const formData = await hooks.getFormData({ - title: 'Update WASM', - size: 'md', - formList: [ - { - form: this.form + if (type === 'add') { + try { + const res = await axios.request({ + method: 'post', + url: `/api/file?api=applet/x/${projectName}`, + headers: { + 'Content-Type': 'multipart/form-data' + }, + data + }); + const appletID = res.data?.appletID; + if (appletID) { + eventBus.emit('applet.create'); } - ] - }); - if (formData.file) { - const data = new FormData(); - const file = dataURItoBlob(formData.file); - data.append('file', file.blob); - data.append( - 'info', - JSON.stringify({ - appletName, - wasmName: file.name, - start: true - }) - ); + } catch (error) { + + } + } + + if (type === 'update') { try { const res = await axios.request({ method: 'put', - url: `/api/file?api=applet/${appletID}`, + url: `/api/file?api=applet/${this.curApplet.f_applet_id}`, headers: { 'Content-Type': 'multipart/form-data' }, data }); - if (res) { + const resourceID = res.data?.resourceID; + if (resourceID) { + this.wasmName.call(resourceID); showNotification({ message: 'update wasm succeeded' }); } } catch (error) { } @@ -532,10 +538,9 @@ export default class AppletModule { async downloadWasmFile() { try { - const curApplet = this.allData.find((item) => item.project_name === globalThis.store.w3s.project.curProject?.name); const res = await axios.request({ method: 'get', - url: `/api/w3bapp/resource/data/${curApplet?.f_resource_id}`, + url: `/api/w3bapp/resource/data/${this.curApplet?.f_resource_id}`, responseType: 'blob' }); let link = document.createElement("a");