polymatica-widget 0.7.1 → 2.0.3

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.
@@ -1,57 +1,47 @@
1
1
  import { Column, DatasetRow } from './dataset';
2
2
  import { Locale } from './locale';
3
3
  import { Theme } from './theme';
4
-
5
- export abstract class Widget {
6
- readonly options!: Options;
7
- readonly theme!: Theme;
8
- readonly lang!: Locale;
9
-
10
- ready(): void {}
11
-
12
- init(): void {}
13
-
4
+ export declare abstract class Widget {
5
+ readonly options: Options;
6
+ readonly theme: Theme;
7
+ readonly lang: Locale;
8
+ ready(): void;
9
+ init(): void;
14
10
  abstract onChange(): void;
15
-
16
- onThemeChange(): void {}
17
- onLangChange(): void {}
11
+ onThemeChange(): void;
12
+ onLangChange(): void;
18
13
  }
19
-
20
14
  export interface SingleData {
21
15
  readonly dataset: Dataset;
22
16
  }
23
-
24
17
  export interface MultiData {
25
- readonly datasets: { [datasetKey: string]: Dataset };
18
+ readonly datasets: {
19
+ [datasetKey: string]: Dataset;
20
+ };
26
21
  }
27
-
28
- export type Repeatable<T extends SingleData | MultiData> = T extends SingleData
29
- ? { readonly datasets: Dataset[] }
30
- : {
31
- readonly datasets: {
32
- [datasetKey: string]: Dataset | Dataset[];
33
- };
34
- };
35
-
22
+ export declare type Repeatable<T extends SingleData | MultiData> = T extends SingleData ? {
23
+ readonly datasets: Dataset[];
24
+ } : {
25
+ readonly datasets: {
26
+ [datasetKey: string]: Dataset | Dataset[];
27
+ };
28
+ };
36
29
  export interface Dataset {
37
30
  columns: Column[];
38
- columnsByBlock: { [blockKey: string]: Column[] };
31
+ columnsByBlock: {
32
+ [blockKey: string]: Column[];
33
+ };
39
34
  rows: DatasetRow[];
40
35
  heatmap: HeatmapItem[];
41
-
42
36
  interact(rowIndex: number): void;
43
-
44
37
  events: {
45
38
  onHighlight: (rowIndexArray: number[]) => void;
46
39
  };
47
40
  }
48
-
49
41
  export interface HeatmapItem {
50
42
  column: Column;
51
-
52
43
  getColor(value: number): string;
53
44
  }
54
-
55
45
  export interface Options {
56
46
  [key: string]: any;
57
47
  }
package/widget.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Widget = void 0;
4
+ class Widget {
5
+ ready() { }
6
+ init() { }
7
+ onThemeChange() { }
8
+ onLangChange() { }
9
+ }
10
+ exports.Widget = Widget;
package/.prettierrc.json DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "arrowParens": "avoid",
3
- "singleQuote": true,
4
- "tabWidth": 4,
5
- "trailingComma": "all"
6
- }
package/scripts/build.js DELETED
@@ -1,23 +0,0 @@
1
- const { writeFileSync: writeFile } = require('fs');
2
- const { join, resolve } = require('path');
3
- const { cp, exec, exit, rm, test } = require('shelljs');
4
-
5
- if (process.cwd() !== join(__dirname, '..')) exit(1);
6
-
7
- if (test('-d', 'package')) rm('-rf', 'package');
8
-
9
- exec('tsc');
10
-
11
- cp('LICENSE', 'README.md', 'package');
12
-
13
- createPackageJSON: {
14
- const source = require('../package.json');
15
-
16
- delete source.scripts;
17
- delete source.devDependencies;
18
-
19
- const path = resolve('package/package.json');
20
- const file = JSON.stringify(source, null, ' ');
21
-
22
- writeFile(path, file);
23
- }
@@ -1,68 +0,0 @@
1
- import { Locale } from '../locale';
2
- import { Theme } from '../theme';
3
- import { Dataset, MultiData, Repeatable, SingleData, Options } from '../widget';
4
-
5
- export enum Input {
6
- Change = 'poly.input.change',
7
- ChangeLang = 'poly.input.changeLang',
8
- ChangeTheme = 'poly.input.changeTheme',
9
- Highlight = 'poly.input.highlight',
10
- }
11
-
12
- export enum Output {
13
- Init = 'poly.output.init',
14
- Ready = 'poly.output.ready',
15
- Interact = 'poly.output.interact',
16
- }
17
-
18
- export type InputDataset = Omit<Dataset, 'interact' | 'events'> & {
19
- datasetId: number;
20
- };
21
-
22
- export interface InputSingleData {
23
- readonly dataset: InputDataset;
24
- }
25
-
26
- export interface InputMultiData {
27
- readonly datasets: { [datasetKey: string]: InputDataset };
28
- }
29
-
30
- export type InputRepeatable<T extends InputSingleData | InputMultiData> =
31
- T extends InputSingleData
32
- ? { readonly datasets: InputDataset[] }
33
- : {
34
- readonly datasets: {
35
- [datasetKey: string]: InputDataset | InputDataset[];
36
- };
37
- };
38
-
39
- export type InputData =
40
- | InputSingleData
41
- | InputMultiData
42
- | InputRepeatable<InputSingleData>
43
- | InputRepeatable<InputMultiData>;
44
-
45
- export interface InputParameter extends Record<Input, any> {
46
- [Input.Change]: [InputData, Options];
47
- [Input.ChangeLang]: Locale;
48
- [Input.ChangeTheme]: Theme;
49
- [Input.Highlight]: {
50
- datasetId: number;
51
- rowIndexArray: number[];
52
- };
53
- }
54
-
55
- export interface OutputParameter extends Record<Output, any> {
56
- [Output.Init]: void;
57
- [Output.Ready]: void;
58
- [Output.Interact]: {
59
- datasetId: number;
60
- dataIndex: number;
61
- };
62
- }
63
-
64
- export interface OutputData {
65
- token: string;
66
- type: Output;
67
- payload?: any;
68
- }
@@ -1,72 +0,0 @@
1
- import { Text } from '../locale';
2
- import { ColumnType } from '../dataset';
3
- import { AggregateFunction } from '../widget-config';
4
-
5
- // enums
6
-
7
- export enum BlockType {
8
- Data = 'data',
9
- Filter = 'filter',
10
- Sort = 'sort',
11
- Heatmap = 'heatmap',
12
- Drilldown = 'drilldown',
13
- RowsLimit = 'rows-limit',
14
- }
15
-
16
- // interfaces
17
-
18
- export interface Block {
19
- type: BlockType;
20
- key: string;
21
- label: Text;
22
- icon?: string;
23
- aggregateFunction?: AggregateFunction;
24
- columnTypes?: ColumnType[];
25
- max?: number;
26
- }
27
-
28
- export function decodeDrilldownData(
29
- source: string,
30
- additionalFilterSources: string[],
31
- ): string {
32
- const keyParts: string[] = [length(source.length), source];
33
-
34
- additionalFilterSources.forEach(item =>
35
- keyParts.push(length(item.length), item),
36
- );
37
-
38
- return keyParts.join('');
39
-
40
- function length(value: number): string {
41
- if (value > 0xff) throw new RangeError();
42
-
43
- return value > 0xf
44
- ? `0x${value.toString(16)}`
45
- : `0x0${value.toString(16)}`;
46
- }
47
- }
48
-
49
- export function encodeDrilldownData(key: string): {
50
- source: string;
51
- additionalFilterSources: string[];
52
- } {
53
- const parts: string[] = [];
54
-
55
- parse();
56
-
57
- const [source, ...additionalFilterSources] = parts;
58
-
59
- return {
60
- source,
61
- additionalFilterSources,
62
- };
63
-
64
- function parse(offset = 0): void {
65
- const start = offset + 4;
66
- const end = start + parseInt(key.slice(offset, start));
67
-
68
- parts.push(key.slice(start, end));
69
-
70
- if (end < key.length) parse(end);
71
- }
72
- }
@@ -1,83 +0,0 @@
1
- import { Text } from '../locale';
2
- import { STEP } from '../widget-config';
3
-
4
- export enum WidgetOptionType {
5
- Text = 'text',
6
- Number = 'number',
7
- Integer = 'integer',
8
- Range = 'range',
9
- Interval = 'interval',
10
- Date = 'date',
11
- Time = 'time',
12
- DateTime = 'datetime',
13
- DateInterval = 'dateinterval',
14
- Checkbox = 'checkbox',
15
- Radio = 'radio',
16
- Select = 'select',
17
- ColorPicker = 'color-picker',
18
- Title = 'title',
19
- }
20
-
21
- export interface WidgetOptionConfig {
22
- type: WidgetOptionType;
23
- key: string;
24
- label: Text;
25
- defaultValue?: any;
26
- options?: { label: Text; value: string | number | boolean }[];
27
- span?: number;
28
- }
29
-
30
- export function valueConversion(type: WidgetOptionType, source: any): any {
31
- switch (type) {
32
- case WidgetOptionType.Text:
33
- return source ? String(source) : '';
34
- case WidgetOptionType.Number:
35
- case WidgetOptionType.Range:
36
- return source ? parseFloat(source) : 0;
37
- case WidgetOptionType.Integer:
38
- return source ? parseInt(source, 10) : 0;
39
- case WidgetOptionType.Interval:
40
- if (source)
41
- return {
42
- from: parseFloat(source.from) || 0,
43
- to: parseFloat(source.to) || 0,
44
- };
45
- return { from: 0, to: 0 };
46
- case WidgetOptionType.Date:
47
- case WidgetOptionType.DateTime:
48
- return parseDate(source);
49
-
50
- case WidgetOptionType.Time:
51
- return source || '00:00';
52
- case WidgetOptionType.DateInterval:
53
- if (source)
54
- return {
55
- from: parseDate(source.from),
56
- to: parseDate(source.to),
57
- };
58
- return { from: new Date(), to: new Date() };
59
- case WidgetOptionType.ColorPicker:
60
- case WidgetOptionType.Radio:
61
- case WidgetOptionType.Select:
62
- return source;
63
- case WidgetOptionType.Checkbox:
64
- return Boolean(source);
65
- default:
66
- return '';
67
- }
68
- }
69
-
70
- function parseDate(source: any): Date {
71
- const data = new Date(source);
72
-
73
- return isNaN(data.valueOf()) ? new Date() : data;
74
- }
75
-
76
- export function getSpan(source?: number): number {
77
- const span = source! | 0;
78
-
79
- if (span > STEP) return STEP;
80
- if (span < 0) return 0;
81
-
82
- return span;
83
- }
package/src/dataset.ts DELETED
@@ -1,22 +0,0 @@
1
- // enums
2
-
3
- export enum ColumnType {
4
- String = 'string',
5
- Number = 'number',
6
- Date = 'date',
7
- Array = 'array',
8
- Object = 'object',
9
- Boolean = 'boolean',
10
- }
11
-
12
- // interfaces
13
-
14
- export interface DatasetRow {
15
- [path: string]: any;
16
- }
17
-
18
- export interface Column {
19
- type: ColumnType;
20
- name: string;
21
- path: string;
22
- }
package/src/declare.ts DELETED
@@ -1,186 +0,0 @@
1
- import { not } from 'logical-not';
2
-
3
- import { Dataset, SingleData, Widget } from './widget';
4
-
5
- import {
6
- Input,
7
- InputData,
8
- InputDataset,
9
- InputParameter,
10
- InputRepeatable,
11
- InputSingleData,
12
- Output,
13
- OutputData,
14
- OutputParameter,
15
- } from './__internal__/io';
16
-
17
- const datasetMap = new Map<number, Dataset>();
18
-
19
- export function Declare(): ClassDecorator {
20
- return (T: any) => {
21
- const instance: Widget = new T();
22
- const token = readFromUrl('token');
23
-
24
- Object.assign(instance, {
25
- options: {},
26
-
27
- ready(): void {
28
- output<Output.Ready>(token, Output.Ready);
29
- },
30
- } as Partial<Widget>);
31
-
32
- let inited = false;
33
-
34
- input<InputParameter[Input.Change]>(Input.Change, ([data, options]) => {
35
- provideTo(instance, data, token);
36
-
37
- set(instance, 'options', options);
38
-
39
- if (not(inited)) {
40
- inited = true;
41
-
42
- call(instance, 'init');
43
- }
44
-
45
- call(instance, 'onChange');
46
- });
47
-
48
- input<InputParameter[Input.ChangeLang]>(Input.ChangeLang, lang => {
49
- set(instance, 'lang', lang);
50
-
51
- if (inited) call(instance, 'onLangChange');
52
- });
53
-
54
- input<InputParameter[Input.ChangeTheme]>(Input.ChangeTheme, theme => {
55
- set(instance, 'theme', theme);
56
-
57
- if (inited) call(instance, 'onThemeChange');
58
- });
59
-
60
- input<InputParameter[Input.Highlight]>(
61
- Input.Highlight,
62
- ({ datasetId, rowIndexArray }) => {
63
- const dataset = datasetMap.get(datasetId);
64
-
65
- dataset?.events.onHighlight(rowIndexArray);
66
- },
67
- );
68
-
69
- output<Output.Init>(token, Output.Init);
70
-
71
- return T;
72
- };
73
- }
74
-
75
- function provideTo(widget: any, source: InputData, token: string): void {
76
- datasetMap.clear();
77
-
78
- if ('dataset' in source) {
79
- const { dataset } = source as InputSingleData;
80
-
81
- Object.assign(widget, {
82
- dataset: transform(dataset, token),
83
- });
84
- } else {
85
- if (Array.isArray(source)) {
86
- const { datasets } = source as InputRepeatable<InputSingleData>;
87
-
88
- Object.assign(widget, {
89
- datasets: datasets.map(dataset => transform(dataset, token)),
90
- });
91
- } else {
92
- const datasets: Record<string, Dataset | Dataset[]> = {};
93
-
94
- Object.entries(source).forEach(
95
- ([key, item]: [string, InputDataset | InputDataset[]]) => {
96
- if (Array.isArray(item)) {
97
- datasets[key] = item.map(dataset =>
98
- transform(dataset, token),
99
- );
100
- } else {
101
- datasets[key] = transform(item, token);
102
- }
103
- },
104
- );
105
-
106
- Object.assign(widget, { datasets });
107
- }
108
- }
109
- }
110
-
111
- function transform(source: InputDataset, token: string): Dataset {
112
- const { datasetId, ...slice } = source;
113
-
114
- const dataset: Dataset = {
115
- ...slice,
116
-
117
- interact(dataIndex: number): void {
118
- output<Output.Interact>(token, Output.Interact, {
119
- datasetId,
120
- dataIndex,
121
- });
122
- },
123
-
124
- events: {
125
- onHighlight() {},
126
- },
127
- };
128
-
129
- datasetMap.set(datasetId, dataset);
130
-
131
- return dataset;
132
- }
133
-
134
- function set<Key extends keyof Widget>(
135
- instance: Widget,
136
- key: Key,
137
- value: Widget[Key],
138
- ): void {
139
- (instance as Writeable<Widget, Key>)[key] = value;
140
- }
141
-
142
- type Writeable<T extends { [x: string]: any }, K extends string> = {
143
- -readonly [P in K]: T[P];
144
- };
145
-
146
- function call(instance: Widget, method: keyof Widget): void {
147
- if (typeof instance[method] === 'function')
148
- (instance[method] as Function)();
149
- }
150
-
151
- interface TransportEvent<TPayload> {
152
- type: Input | Output;
153
- payload: TPayload;
154
- token?: string;
155
- }
156
-
157
- function input<TPayload = void>(
158
- type: Input,
159
- callback: (payload: TPayload) => void,
160
- ): void {
161
- window.addEventListener(
162
- 'message',
163
- ({ data }: MessageEvent<TransportEvent<TPayload>>) => {
164
- if (data.type === type) callback(data.payload);
165
- },
166
- );
167
- }
168
-
169
- function output<T extends Output>(
170
- token: string,
171
- type: T,
172
- payload?: OutputParameter[T],
173
- ): void {
174
- const message: OutputData = { type, token, payload };
175
-
176
- window.parent.postMessage(message, '*');
177
- }
178
-
179
- function readFromUrl(key: string): string {
180
- const startsWith = key + '=';
181
- const source = window.location.search
182
- .split(/[?&]/)
183
- .find(item => item.startsWith(startsWith));
184
-
185
- return source ? source.slice(startsWith.length) : '';
186
- }
package/src/locale.ts DELETED
@@ -1,2 +0,0 @@
1
- export type Locale = 'ru' | 'en';
2
- export type Text = Record<Locale, string>;