@things-factory/board-ui 6.1.40 → 6.1.48

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.
@@ -0,0 +1,14 @@
1
+ import '@operato/board/ox-board-selector.js';
2
+ import './board-renderer';
3
+ import { OxGristEditor } from '@operato/data-grist';
4
+ export declare class LegendEditor extends OxGristEditor {
5
+ static styles: import("lit").CSSResult;
6
+ value: any;
7
+ column: any;
8
+ record: any;
9
+ row?: number;
10
+ popup: any;
11
+ render(): import("lit-html").TemplateResult<1>;
12
+ firstUpdated(): Promise<void>;
13
+ openSelector(): void;
14
+ }
@@ -0,0 +1,108 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@operato/board/ox-board-selector.js';
3
+ import './board-renderer';
4
+ import { css, html } from 'lit';
5
+ import { customElement, property } from 'lit/decorators.js';
6
+ import { OxGristEditor } from '@operato/data-grist';
7
+ import { i18next } from '@operato/i18n';
8
+ import { openPopup } from '@operato/layout';
9
+ let LegendEditor = class LegendEditor extends OxGristEditor {
10
+ render() {
11
+ var { boardViewerPage } = this.column.record.options || {};
12
+ return html ` <board-renderer .value=${this.value} .boardViewerPage=${boardViewerPage}></board-renderer> `;
13
+ }
14
+ async firstUpdated() {
15
+ this.value = this.record[this.column.name];
16
+ await this.updateComplete;
17
+ this.renderRoot.addEventListener('click', e => {
18
+ e.stopPropagation();
19
+ this.openSelector();
20
+ });
21
+ this.openSelector();
22
+ }
23
+ openSelector() {
24
+ if (this.popup) {
25
+ delete this.popup;
26
+ }
27
+ /*
28
+ * 기존 설정된 보드가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.
29
+ * 주의. value는 object일 수도 있고, string일 수도 있다.
30
+ * string인 경우에는 해당 보드의 id로 해석한다.
31
+ */
32
+ var value = this.value || {};
33
+ var template = html `
34
+ <ox-board-selector
35
+ .creatable=${true}
36
+ .value=${this.value}
37
+ @board-selected=${async (e) => {
38
+ var board = e.detail.board;
39
+ this.dispatchEvent(new CustomEvent('field-change', {
40
+ bubbles: true,
41
+ composed: true,
42
+ detail: {
43
+ before: this.value,
44
+ after: this.column.type == 'board' ? board : board.id || '',
45
+ record: this.record,
46
+ column: this.column,
47
+ row: this.row
48
+ }
49
+ }));
50
+ this.popup && this.popup.close();
51
+ }}
52
+ ></ox-board-selector>
53
+ `;
54
+ this.popup = openPopup(template, {
55
+ backdrop: true,
56
+ size: 'large',
57
+ title: i18next.t('title.select board')
58
+ });
59
+ }
60
+ };
61
+ LegendEditor.styles = css `
62
+ :host {
63
+ display: flex;
64
+ flex-flow: row nowrap;
65
+ align-items: center;
66
+
67
+ box-sizing: border-box;
68
+
69
+ width: 100%;
70
+ height: 100%;
71
+
72
+ border: 0;
73
+ background-color: transparent;
74
+
75
+ font: var(--grist-object-editor-font);
76
+ color: var(--grist-object-editor-color);
77
+
78
+ justify-content: inherit;
79
+ }
80
+
81
+ board-renderer {
82
+ display: flex;
83
+ flex: auto;
84
+
85
+ justify-content: inherit;
86
+ }
87
+ `;
88
+ __decorate([
89
+ property({ type: Object }),
90
+ __metadata("design:type", Object)
91
+ ], LegendEditor.prototype, "value", void 0);
92
+ __decorate([
93
+ property({ type: Object }),
94
+ __metadata("design:type", Object)
95
+ ], LegendEditor.prototype, "column", void 0);
96
+ __decorate([
97
+ property({ type: Object }),
98
+ __metadata("design:type", Object)
99
+ ], LegendEditor.prototype, "record", void 0);
100
+ __decorate([
101
+ property({ type: Number }),
102
+ __metadata("design:type", Number)
103
+ ], LegendEditor.prototype, "row", void 0);
104
+ LegendEditor = __decorate([
105
+ customElement('legend-editor')
106
+ ], LegendEditor);
107
+ export { LegendEditor };
108
+ //# sourceMappingURL=legend-editor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"legend-editor.js","sourceRoot":"","sources":["../../client/data-grist/legend-editor.ts"],"names":[],"mappings":"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","sourcesContent":["import '@operato/board/ox-board-selector.js'\nimport './board-renderer'\n\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, query } from 'lit/decorators.js'\n\nimport { OxGristEditor } from '@operato/data-grist'\nimport { i18next } from '@operato/i18n'\nimport { openPopup } from '@operato/layout'\n\n@customElement('legend-editor')\nexport class LegendEditor extends OxGristEditor {\n static styles = css`\n :host {\n display: flex;\n flex-flow: row nowrap;\n align-items: center;\n\n box-sizing: border-box;\n\n width: 100%;\n height: 100%;\n\n border: 0;\n background-color: transparent;\n\n font: var(--grist-object-editor-font);\n color: var(--grist-object-editor-color);\n\n justify-content: inherit;\n }\n\n board-renderer {\n display: flex;\n flex: auto;\n\n justify-content: inherit;\n }\n `\n\n @property({ type: Object }) value: any\n @property({ type: Object }) column: any\n @property({ type: Object }) record: any\n @property({ type: Number }) row?: number\n\n popup\n\n render() {\n var { boardViewerPage } = this.column.record.options || {}\n return html` <board-renderer .value=${this.value} .boardViewerPage=${boardViewerPage}></board-renderer> `\n }\n\n async firstUpdated() {\n this.value = this.record[this.column.name]\n\n await this.updateComplete\n\n this.renderRoot.addEventListener('click', e => {\n e.stopPropagation()\n\n this.openSelector()\n })\n\n this.openSelector()\n }\n\n openSelector() {\n if (this.popup) {\n delete this.popup\n }\n\n /*\n * 기존 설정된 보드가 선택된 상태가 되게 하기 위해서는 selector에 value를 전달해줄 필요가 있음.\n * 주의. value는 object일 수도 있고, string일 수도 있다.\n * string인 경우에는 해당 보드의 id로 해석한다.\n */\n var value = this.value || {}\n\n var template = html`\n <ox-board-selector\n .creatable=${true}\n .value=${this.value}\n @board-selected=${async e => {\n var board = e.detail.board\n\n this.dispatchEvent(\n new CustomEvent('field-change', {\n bubbles: true,\n composed: true,\n detail: {\n before: this.value,\n after: this.column.type == 'board' ? board : board.id || '',\n record: this.record,\n column: this.column,\n row: this.row\n }\n })\n )\n\n this.popup && this.popup.close()\n }}\n ></ox-board-selector>\n `\n\n this.popup = openPopup(template, {\n backdrop: true,\n size: 'large',\n title: i18next.t('title.select board')\n })\n }\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import '@operato/data-grist';
2
2
  import { LitElement } from 'lit';
3
- export declare class ShareImporter extends LitElement {
3
+ export declare class ThemeImporter extends LitElement {
4
4
  static styles: import("lit").CSSResult[];
5
- shares: any[];
5
+ themes: any[];
6
6
  columns: {
7
7
  list: {
8
8
  fields: string[];
@@ -1,18 +1,18 @@
1
1
  import '@operato/data-grist';
2
2
  import { PageView } from '@operato/shell';
3
3
  import { FetchOption } from '@operato/data-grist';
4
- import { ShareImporter } from './share-importer';
5
- declare const ShareListPage_base: (new (...args: any[]) => {
4
+ import { ThemeImporter } from './theme-importer';
5
+ declare const ThemeListPage_base: (new (...args: any[]) => {
6
6
  _storeUnsubscribe: import("redux").Unsubscribe;
7
7
  connectedCallback(): void;
8
8
  disconnectedCallback(): void;
9
9
  stateChanged(_state: unknown): void;
10
10
  readonly isConnected: boolean;
11
11
  }) & (new (...args: any[]) => import("lit").LitElement) & typeof PageView & import("@open-wc/dedupe-mixin").Constructor<import("@open-wc/scoped-elements/types/src/types").ScopedElementsHost>;
12
- export declare class ShareListPage extends ShareListPage_base {
12
+ export declare class ThemeListPage extends ThemeListPage_base {
13
13
  static styles: import("lit").CSSResult[];
14
14
  static get scopedElements(): {
15
- 'share-importer': typeof ShareImporter;
15
+ 'theme-importer': typeof ThemeImporter;
16
16
  };
17
17
  gristConfig: any;
18
18
  mode: 'CARD' | 'GRID' | 'LIST';
@@ -54,8 +54,8 @@ export declare class ShareListPage extends ShareListPage_base {
54
54
  total: any;
55
55
  records: any;
56
56
  }>;
57
- _deleteShare(): Promise<void>;
58
- _updateShare(): Promise<void>;
57
+ _deleteTheme(): Promise<void>;
58
+ _updateTheme(): Promise<void>;
59
59
  exportHandler(): Promise<{}[]>;
60
60
  importHandler(records: any): Promise<void>;
61
61
  }
@@ -1,5 +1,5 @@
1
1
  export declare function buildThemeValueRecordConfig(): {
2
2
  editor: (value: any, column: any, record: any, rowIndex: any, field: any) => import("@operato/data-grist").OxGristEditor;
3
- renderer: (value: any, column: any, record: any, rowIndex: any, field: any) => string | void | import("lit-html").TemplateResult<2 | 1> | import("@operato/data-grist/dist/src/renderers/ox-grist-renderer").OxGristRenderer;
3
+ renderer: (value: any, column: any, record: any, rowIndex: any, field: any) => string | void | import("lit-html").TemplateResult<1 | 2> | import("@operato/data-grist/dist/src/renderers/ox-grist-renderer").OxGristRenderer;
4
4
  editable: boolean;
5
5
  };
@@ -0,0 +1,22 @@
1
+ import '@operato/data-grist';
2
+ import { LitElement } from 'lit';
3
+ export declare class ThemeImporter extends LitElement {
4
+ static styles: import("lit").CSSResult[];
5
+ themes: any[];
6
+ columns: {
7
+ list: {
8
+ fields: string[];
9
+ };
10
+ pagination: {
11
+ infinite: boolean;
12
+ };
13
+ columns: {
14
+ type: string;
15
+ name: string;
16
+ header: string;
17
+ width: number;
18
+ }[];
19
+ };
20
+ render(): import("lit-html").TemplateResult<1>;
21
+ save(): Promise<void>;
22
+ }
@@ -0,0 +1,100 @@
1
+ import { __decorate, __metadata } from "tslib";
2
+ import '@operato/data-grist';
3
+ import gql from 'graphql-tag';
4
+ import { css, html, LitElement } from 'lit';
5
+ import { property } from 'lit/decorators.js';
6
+ import { client } from '@operato/graphql';
7
+ import { i18next } from '@operato/i18n';
8
+ import { isMobileDevice } from '@operato/utils';
9
+ export class ThemeImporter extends LitElement {
10
+ constructor() {
11
+ super(...arguments);
12
+ this.themes = [];
13
+ this.columns = {
14
+ list: { fields: ['name', 'description'] },
15
+ pagination: { infinite: true },
16
+ columns: [
17
+ {
18
+ type: 'string',
19
+ name: 'name',
20
+ header: i18next.t('field.name'),
21
+ width: 150
22
+ },
23
+ {
24
+ type: 'string',
25
+ name: 'description',
26
+ header: i18next.t('field.description'),
27
+ width: 200
28
+ },
29
+ {
30
+ type: 'checkbox',
31
+ name: 'active',
32
+ header: i18next.t('field.active'),
33
+ width: 60
34
+ }
35
+ ]
36
+ };
37
+ }
38
+ render() {
39
+ return html `
40
+ <ox-grist
41
+ .mode=${isMobileDevice() ? 'LIST' : 'GRID'}
42
+ .config=${this.columns}
43
+ .data=${{
44
+ records: this.themes
45
+ }}
46
+ ></ox-grist>
47
+
48
+ <div class="button-container">
49
+ <mwc-button raised @click="${this.save.bind(this)}">${i18next.t('button.save')}</mwc-button>
50
+ </div>
51
+ `;
52
+ }
53
+ async save() {
54
+ var _a;
55
+ const response = await client.mutate({
56
+ mutation: gql `
57
+ mutation importThemes($themes: [ThemePatch!]!) {
58
+ importThemes(themes: $themes)
59
+ }
60
+ `,
61
+ variables: { themes: this.themes }
62
+ });
63
+ if ((_a = response.errors) === null || _a === void 0 ? void 0 : _a.length)
64
+ return;
65
+ this.dispatchEvent(new CustomEvent('imported'));
66
+ }
67
+ }
68
+ ThemeImporter.styles = [
69
+ css `
70
+ :host {
71
+ display: flex;
72
+ flex-direction: column;
73
+
74
+ background-color: #fff;
75
+ }
76
+
77
+ ox-grist {
78
+ flex: 1;
79
+ }
80
+
81
+ .button-container {
82
+ display: flex;
83
+ margin-left: auto;
84
+ padding: var(--padding-default);
85
+ }
86
+
87
+ mwc-button {
88
+ margin-left: var(--margin-default);
89
+ }
90
+ `
91
+ ];
92
+ __decorate([
93
+ property({ type: Array }),
94
+ __metadata("design:type", Array)
95
+ ], ThemeImporter.prototype, "themes", void 0);
96
+ __decorate([
97
+ property({ type: Object }),
98
+ __metadata("design:type", Object)
99
+ ], ThemeImporter.prototype, "columns", void 0);
100
+ //# sourceMappingURL=theme-importer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-importer.js","sourceRoot":"","sources":["../../../client/pages/theme/theme-importer.ts"],"names":[],"mappings":";AAAA,OAAO,qBAAqB,CAAA;AAE5B,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,OAAO,aAAc,SAAQ,UAAU;IAA7C;;QA0B6B,WAAM,GAAU,EAAE,CAAA;QACjB,YAAO,GAAG;YACpC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,MAAM,EAAE,aAAa,CAAC,EAAE;YACzC,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;YAC9B,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,MAAM;oBACZ,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBAC/B,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,aAAa;oBACnB,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;oBACtC,KAAK,EAAE,GAAG;iBACX;gBACD;oBACE,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC;oBACjC,KAAK,EAAE,EAAE;iBACV;aACF;SACF,CAAA;IAgCH,CAAC;IA9BC,MAAM;QACJ,OAAO,IAAI,CAAA;;gBAEC,cAAc,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;kBAChC,IAAI,CAAC,OAAO;gBACd;YACN,OAAO,EAAE,IAAI,CAAC,MAAM;SACrB;;;;qCAI4B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC;;KAEjF,CAAA;IACH,CAAC;IAED,KAAK,CAAC,IAAI;;QACR,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YACnC,QAAQ,EAAE,GAAG,CAAA;;;;OAIZ;YACD,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE;SACnC,CAAC,CAAA;QAEF,IAAI,MAAA,QAAQ,CAAC,MAAM,0CAAE,MAAM;YAAE,OAAM;QAEnC,IAAI,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,CAAC,CAAA;IACjD,CAAC;;AAhFM,oBAAM,GAAG;IACd,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;KAqBF;CACF,CAAA;AAED;IAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;6CAAmB;AAC7C;IAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;8CAuB1B","sourcesContent":["import '@operato/data-grist'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { property } from 'lit/decorators.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\nimport { isMobileDevice } from '@operato/utils'\n\nexport class ThemeImporter extends LitElement {\n static styles = [\n css`\n :host {\n display: flex;\n flex-direction: column;\n\n background-color: #fff;\n }\n\n ox-grist {\n flex: 1;\n }\n\n .button-container {\n display: flex;\n margin-left: auto;\n padding: var(--padding-default);\n }\n\n mwc-button {\n margin-left: var(--margin-default);\n }\n `\n ]\n\n @property({ type: Array }) themes: any[] = []\n @property({ type: Object }) columns = {\n list: { fields: ['name', 'description'] },\n pagination: { infinite: true },\n columns: [\n {\n type: 'string',\n name: 'name',\n header: i18next.t('field.name'),\n width: 150\n },\n {\n type: 'string',\n name: 'description',\n header: i18next.t('field.description'),\n width: 200\n },\n {\n type: 'checkbox',\n name: 'active',\n header: i18next.t('field.active'),\n width: 60\n }\n ]\n }\n\n render() {\n return html`\n <ox-grist\n .mode=${isMobileDevice() ? 'LIST' : 'GRID'}\n .config=${this.columns}\n .data=${{\n records: this.themes\n }}\n ></ox-grist>\n\n <div class=\"button-container\">\n <mwc-button raised @click=\"${this.save.bind(this)}\">${i18next.t('button.save')}</mwc-button>\n </div>\n `\n }\n\n async save() {\n const response = await client.mutate({\n mutation: gql`\n mutation importThemes($themes: [ThemePatch!]!) {\n importThemes(themes: $themes)\n }\n `,\n variables: { themes: this.themes }\n })\n\n if (response.errors?.length) return\n\n this.dispatchEvent(new CustomEvent('imported'))\n }\n}\n"]}