@platforma-sdk/ui-vue 1.7.34 → 1.7.36

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": "@platforma-sdk/ui-vue",
3
- "version": "1.7.34",
3
+ "version": "1.7.36",
4
4
  "type": "module",
5
5
  "main": "dist/lib.umd.cjs",
6
6
  "module": "dist/lib.js",
@@ -18,23 +18,23 @@
18
18
  "./*": "./*"
19
19
  },
20
20
  "dependencies": {
21
- "lru-cache": "^11.0.1",
21
+ "lru-cache": "^11.0.2",
22
22
  "vue": "^3.5.12",
23
23
  "canonicalize": "^2.0.0",
24
- "@ag-grid-community/core": "^32.3.0",
25
- "@ag-grid-community/client-side-row-model": "^32.3.0",
26
- "@ag-grid-community/infinite-row-model": "^32.3.0",
27
- "@ag-grid-enterprise/server-side-row-model": "^32.3.0",
28
- "@ag-grid-community/styles": "^32.3.0",
29
- "@ag-grid-community/vue3": "^32.3.0",
30
- "@ag-grid-community/csv-export": "^32.3.0",
31
- "@ag-grid-enterprise/core": "^32.3.0",
32
- "@ag-grid-enterprise/clipboard": "^32.3.0",
33
- "@ag-grid-enterprise/range-selection": "^32.3.0",
34
- "@ag-grid-enterprise/rich-select": "^32.3.0",
35
- "@ag-grid-enterprise/menu": "^32.3.0",
36
- "@ag-grid-enterprise/excel-export": "^32.3.0",
37
- "@milaboratories/uikit": "^2.0.1",
24
+ "@ag-grid-community/core": "^32.3.2",
25
+ "@ag-grid-community/client-side-row-model": "^32.3.2",
26
+ "@ag-grid-community/infinite-row-model": "^32.3.2",
27
+ "@ag-grid-enterprise/server-side-row-model": "^32.3.2",
28
+ "@ag-grid-community/styles": "^32.3.2",
29
+ "@ag-grid-community/vue3": "^32.3.2",
30
+ "@ag-grid-community/csv-export": "^32.3.2",
31
+ "@ag-grid-enterprise/core": "^32.3.2",
32
+ "@ag-grid-enterprise/clipboard": "^32.3.2",
33
+ "@ag-grid-enterprise/range-selection": "^32.3.2",
34
+ "@ag-grid-enterprise/rich-select": "^32.3.2",
35
+ "@ag-grid-enterprise/menu": "^32.3.2",
36
+ "@ag-grid-enterprise/excel-export": "^32.3.2",
37
+ "@milaboratories/uikit": "^2.0.3",
38
38
  "@platforma-sdk/model": "^1.7.20"
39
39
  },
40
40
  "devDependencies": {
@@ -43,7 +43,7 @@
43
43
  "@types/node": "~20.16.15",
44
44
  "@typescript-eslint/eslint-plugin": "^7.18.0",
45
45
  "@vitejs/plugin-vue": "^5.1.4",
46
- "@vueuse/core": "^11.1.0",
46
+ "@vueuse/core": "^11.2.0",
47
47
  "canonicalize": "^2.0.0",
48
48
  "eslint": "^8.57.1",
49
49
  "eslint-config-prettier": "^9.1.0",
@@ -54,7 +54,7 @@
54
54
  "sass": "~1.77.8",
55
55
  "typescript": "~5.5.4",
56
56
  "vite": "^5.4.10",
57
- "vitest": "^2.1.3",
57
+ "vitest": "^2.1.4",
58
58
  "vue-tsc": "^2.1.6",
59
59
  "zod": "^3.23.8",
60
60
  "yarpm": "^1.2.0",
@@ -5,6 +5,7 @@ import { computed } from 'vue';
5
5
  import { useSdkPlugin } from '../defineApp';
6
6
  import NotFound from './NotFound.vue';
7
7
  import LoaderPage from './LoaderPage.vue';
8
+ import { PlAppErrorNotificationAlert } from './PlAppErrorNotificationAlert';
8
9
 
9
10
  const sdk = useSdkPlugin();
10
11
 
@@ -28,6 +29,12 @@ const CurrentView = computed(() => {
28
29
 
29
30
  return undefined;
30
31
  });
32
+
33
+ const app = computed(() => (sdk.loaded ? sdk.useApp() : undefined));
34
+
35
+ const errors = computed(() => (app.value ? app.value.model.outputErrors : {}));
36
+
37
+ const showErrorsNotification = computed(() => app.value?.showErrorsNotification);
31
38
  </script>
32
39
 
33
40
  <template>
@@ -36,5 +43,6 @@ const CurrentView = computed(() => {
36
43
  <LoaderPage v-else-if="!sdk.loaded">Loading...</LoaderPage>
37
44
  <component :is="CurrentView" v-else-if="CurrentView" :key="href" />
38
45
  <NotFound v-else />
46
+ <PlAppErrorNotificationAlert v-if="sdk.loaded && showErrorsNotification" :errors="errors" />
39
47
  </div>
40
48
  </template>
@@ -0,0 +1,59 @@
1
+ <script setup lang="ts">
2
+ import type { BlockOutputsBase } from '@platforma-sdk/model';
3
+ import type { OutputErrors } from '../../types';
4
+ // @TODO module
5
+ import './pl-app-error-notification-alert.scss';
6
+ import { PlBtnPrimary, PlDialogModal, PlNotificationAlert, PlSpacer, PlCopyData } from '@milaboratories/uikit';
7
+ import { ref, watch } from 'vue';
8
+
9
+ const props = defineProps<{ errors: OutputErrors<BlockOutputsBase> }>();
10
+
11
+ const isModalOpen = ref(false);
12
+
13
+ const isAlertOpen = ref(true);
14
+
15
+ function showErrors() {
16
+ isModalOpen.value = true;
17
+ }
18
+
19
+ function copyData(data: OutputErrors<BlockOutputsBase>[string]) {
20
+ if (navigator.clipboard) {
21
+ navigator.clipboard.writeText(JSON.stringify(data));
22
+ }
23
+ }
24
+
25
+ // @TODO (temp)
26
+ watch(
27
+ () => props.errors,
28
+ (errors) => {
29
+ isAlertOpen.value = Object.values(errors).some((v) => !!v);
30
+ },
31
+ { immediate: true, deep: true },
32
+ );
33
+ </script>
34
+ <template>
35
+ <div class="pl-app-notification-alert">
36
+ <PlDialogModal v-model="isModalOpen" width="50%" style="max-height: 100vh">
37
+ <template #title> Errors </template>
38
+ <div class="pl-app-notification-alert__content">
39
+ <div v-for="(err, name) in errors" :key="name" class="pl-app-notification-alert__item">
40
+ <div class="pl-app-notification-alert__title">{{ name }}</div>
41
+ <div class="pl-app-notification-alert__error-description">
42
+ <code>
43
+ {{ err?.message }}
44
+ </code>
45
+ <PlCopyData class="pl-app-notification-alert__copy-icon" @copy-data="copyData(err)" />
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </PlDialogModal>
50
+
51
+ <PlNotificationAlert v-model="isAlertOpen" type="error" closable>
52
+ Output failed. Review block logic and retry
53
+ <template #actions>
54
+ <PlSpacer />
55
+ <PlBtnPrimary @click="showErrors">Show errors</PlBtnPrimary>
56
+ </template>
57
+ </PlNotificationAlert>
58
+ </div>
59
+ </template>
@@ -0,0 +1 @@
1
+ export { default as PlAppErrorNotificationAlert } from './PlAppErrorNotificationAlert.vue';
@@ -0,0 +1,51 @@
1
+ @import '@milaboratories/uikit/src/assets/mixins.scss';
2
+
3
+ .pl-app-notification-alert {
4
+ position: fixed;
5
+ bottom: 12px;
6
+ right: 12px;
7
+ width: 256px;
8
+ height: auto;
9
+
10
+ &__content {
11
+ display: flex;
12
+ flex-direction: column;
13
+ gap: 12px;
14
+ max-height: 100%;
15
+ }
16
+
17
+ &__error-description {
18
+ display: flex;
19
+ border-radius: 6px;
20
+ border: 1px solid var(--border-color-div-grey);
21
+ background: var(--bg-base-light);
22
+ max-height: 600px; // @TODO
23
+ position: relative;
24
+ > code {
25
+ white-space: pre-wrap;
26
+ display: block;
27
+ padding: 12px 4px 24px 12px;
28
+ @include scrollbar();
29
+ }
30
+ }
31
+
32
+ &__copy-icon {
33
+ top: 12px;
34
+ right: 12px;
35
+ position: absolute;
36
+ background: var(--ic-02);
37
+ }
38
+
39
+ &__item {
40
+ position: relative;
41
+ }
42
+
43
+ &__title {
44
+ color: var(--txt-01);
45
+ font-size: 14px;
46
+ font-style: normal;
47
+ font-weight: 600;
48
+ line-height: 20px;
49
+ margin-bottom: 6px;
50
+ }
51
+ }
package/src/defineApp.ts CHANGED
@@ -3,7 +3,7 @@ import { type BlockOutputsBase, type Platforma } from '@platforma-sdk/model';
3
3
  import type { Component, Reactive } from 'vue';
4
4
  import { inject, markRaw, reactive } from 'vue';
5
5
  import { createApp, type BaseApp } from './internal/createApp';
6
- import type { LocalState, Routes } from './types';
6
+ import type { BaseSettings, Routes } from './types';
7
7
  import { activateAgGrid } from './aggrid';
8
8
 
9
9
  const pluginKey = Symbol('sdk-vue');
@@ -18,7 +18,7 @@ export function defineApp<
18
18
  Outputs extends BlockOutputsBase = BlockOutputsBase,
19
19
  UiState = unknown,
20
20
  Href extends `/${string}` = `/${string}`,
21
- Local extends LocalState<Href> = LocalState<Href>,
21
+ Local extends BaseSettings<Href> = BaseSettings<Href>,
22
22
  >(
23
23
  platforma: Platforma<Args, Outputs, UiState, Href>,
24
24
  extendApp: (app: BaseApp<Args, Outputs, UiState, Href>) => Local,
@@ -79,7 +79,7 @@ export type App<
79
79
  Outputs extends BlockOutputsBase = BlockOutputsBase,
80
80
  UiState = unknown,
81
81
  Href extends `/${string}` = `/${string}`,
82
- Local extends LocalState<Href> = LocalState<Href>,
82
+ Local extends BaseSettings<Href> = BaseSettings<Href>,
83
83
  > = BaseApp<Args, Outputs, UiState, Href> & Reactive<Omit<Local, 'routes'>> & { getRoute(href: Href): Component | undefined };
84
84
 
85
85
  export type SdkPlugin<
@@ -87,7 +87,7 @@ export type SdkPlugin<
87
87
  Outputs extends BlockOutputsBase = BlockOutputsBase,
88
88
  UiState = unknown,
89
89
  Href extends `/${string}` = `/${string}`,
90
- Local extends LocalState<Href> = LocalState<Href>,
90
+ Local extends BaseSettings<Href> = BaseSettings<Href>,
91
91
  > = {
92
92
  loaded: boolean;
93
93
  error: unknown;
@@ -83,7 +83,8 @@ export function createAppModel<
83
83
  const valid = computed(() => !error.value);
84
84
 
85
85
  const isChanged = computed(() => {
86
- return !isJsonEqual(options.get(), unref(local));
86
+ const { args, ui } = unref(local)?.model ?? {};
87
+ return !isJsonEqual(options.get(), { args, ui });
87
88
  });
88
89
 
89
90
  const errorString = computed(() => (error.value ? error.value.message : ''));
package/src/types.ts CHANGED
@@ -51,7 +51,8 @@ export type RouteParams<Href extends `/${string}` = `/${string}`> = {
51
51
  [P in Href as ParsePathnamePart<P>]: ParseQuery<P>;
52
52
  };
53
53
 
54
- export type LocalState<Href extends `/${string}` = `/${string}`> = {
54
+ export type BaseSettings<Href extends `/${string}` = `/${string}`> = {
55
+ showErrorsNotification?: boolean;
55
56
  routes: Routes<Href>;
56
57
  };
57
58
 
package/src/utils.ts CHANGED
@@ -7,12 +7,12 @@ export class UnresolvedError extends Error {}
7
7
 
8
8
  export class MultiError extends Error {
9
9
  constructor(public readonly errors: string[]) {
10
- super();
10
+ super(errors.join('\n'));
11
11
  }
12
12
 
13
13
  // @todo
14
14
  toString() {
15
- return this.errors.join(',');
15
+ return this.errors.join('\n');
16
16
  }
17
17
  }
18
18