@things-factory/board-ui 10.0.0-beta.71 → 10.0.0-beta.72
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/dist-client/board-list/board-tile-list.d.ts +0 -2
- package/dist-client/board-list/board-tile-list.js +29 -22
- package/dist-client/board-list/board-tile-list.js.map +1 -1
- package/dist-client/graphql/attachment.d.ts +33 -0
- package/dist-client/graphql/attachment.js +87 -0
- package/dist-client/graphql/attachment.js.map +1 -0
- package/dist-client/graphql/board-import.d.ts +45 -0
- package/dist-client/graphql/board-import.js +104 -0
- package/dist-client/graphql/board-import.js.map +1 -0
- package/dist-client/pages/board-create-wizard-page.d.ts +157 -0
- package/dist-client/pages/board-create-wizard-page.js +2176 -0
- package/dist-client/pages/board-create-wizard-page.js.map +1 -0
- package/dist-client/route.d.ts +1 -1
- package/dist-client/route.js +3 -0
- package/dist-client/route.js.map +1 -1
- package/dist-client/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/things-factory.config.js +1 -0
- package/translations/en.json +68 -1
- package/translations/ko.json +68 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import '@material/web/icon/icon.js';
|
|
2
|
-
import '@operato/board/ox-board-creation-card.js';
|
|
3
2
|
import { LitElement, PropertyValues } from 'lit';
|
|
4
3
|
export declare class BoardTileList extends LitElement {
|
|
5
4
|
static styles: import("lit").CSSResult[];
|
|
@@ -19,7 +18,6 @@ export declare class BoardTileList extends LitElement {
|
|
|
19
18
|
private _resetDragState;
|
|
20
19
|
render(): import("lit-html").TemplateResult<1>;
|
|
21
20
|
updated(changes: PropertyValues<this>): void;
|
|
22
|
-
onCreateBoard(e: any): void;
|
|
23
21
|
infoBoard(board: any): void;
|
|
24
22
|
removeFavorite(boardId: any): Promise<void>;
|
|
25
23
|
addFavorite(boardId: any): Promise<void>;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { __decorate, __metadata } from "tslib";
|
|
2
2
|
import '@material/web/icon/icon.js';
|
|
3
|
-
import '@operato/board/ox-board-creation-card.js';
|
|
4
3
|
import gql from 'graphql-tag';
|
|
5
4
|
import { css, html, LitElement, nothing } from 'lit';
|
|
6
5
|
import { customElement, property } from 'lit/decorators.js';
|
|
7
6
|
import { repeat } from 'lit/directives/repeat.js';
|
|
8
7
|
import { client } from '@operato/graphql';
|
|
8
|
+
import { i18next } from '@operato/i18n';
|
|
9
9
|
import { privileged } from '@things-factory/auth-base/dist-client/index.js';
|
|
10
10
|
let BoardTileList = class BoardTileList extends LitElement {
|
|
11
11
|
constructor() {
|
|
@@ -44,6 +44,28 @@ let BoardTileList = class BoardTileList extends LitElement {
|
|
|
44
44
|
background-color: initial;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
[card][import-card] > a {
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
justify-content: center;
|
|
51
|
+
height: calc(100% - 25px);
|
|
52
|
+
border: 1px dashed var(--md-sys-color-outline-variant, #b8c2cc);
|
|
53
|
+
border-radius: var(--card-list-border-radius, 8px);
|
|
54
|
+
text-decoration: none;
|
|
55
|
+
color: var(--md-sys-color-on-secondary-container, #555);
|
|
56
|
+
background: var(--md-sys-color-surface-container, #fff);
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
}
|
|
59
|
+
[card][import-card] > a:hover {
|
|
60
|
+
border-color: var(--md-sys-color-primary, #2a64d8);
|
|
61
|
+
color: var(--md-sys-color-primary, #2a64d8);
|
|
62
|
+
background: var(--md-sys-color-primary-container, #eaf2ff);
|
|
63
|
+
}
|
|
64
|
+
[card][import-card] md-icon {
|
|
65
|
+
font-size: 48px;
|
|
66
|
+
--md-icon-size: 48px;
|
|
67
|
+
}
|
|
68
|
+
|
|
47
69
|
[card] > a {
|
|
48
70
|
display: flex;
|
|
49
71
|
clip-path: border-box;
|
|
@@ -209,11 +231,6 @@ let BoardTileList = class BoardTileList extends LitElement {
|
|
|
209
231
|
animation: surface-flash 1.5s ease-out;
|
|
210
232
|
}
|
|
211
233
|
|
|
212
|
-
@media screen and (max-width: 800px), screen and (max-height: 600px) {
|
|
213
|
-
ox-board-creation-card {
|
|
214
|
-
display: none;
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
234
|
`
|
|
218
235
|
]; }
|
|
219
236
|
connectedCallback() {
|
|
@@ -385,13 +402,12 @@ let BoardTileList = class BoardTileList extends LitElement {
|
|
|
385
402
|
return html `
|
|
386
403
|
${this.creatable
|
|
387
404
|
? privileged({ privilege: 'mutation', category: 'board' }, html `
|
|
388
|
-
<
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
></ox-board-creation-card>
|
|
405
|
+
<div card import-card>
|
|
406
|
+
<a href="board-create" title=${i18next.t('text.create board') || 'Create New Board'}>
|
|
407
|
+
<md-icon>add_circle_outline</md-icon>
|
|
408
|
+
</a>
|
|
409
|
+
<div name>${i18next.t('label.create board') || 'Create Board'}</div>
|
|
410
|
+
</div>
|
|
395
411
|
`)
|
|
396
412
|
: nothing}
|
|
397
413
|
${repeat(boards, board => board.id, board => html `
|
|
@@ -419,10 +435,6 @@ let BoardTileList = class BoardTileList extends LitElement {
|
|
|
419
435
|
`;
|
|
420
436
|
}
|
|
421
437
|
updated(changes) {
|
|
422
|
-
const creationCard = this.renderRoot.querySelector('ox-board-creation-card');
|
|
423
|
-
if (creationCard) {
|
|
424
|
-
creationCard.reset();
|
|
425
|
-
}
|
|
426
438
|
if (changes.has('updatedIds') && this.updatedIds.length > 0) {
|
|
427
439
|
const animClasses = ['anim-sweep', 'anim-pulse', 'anim-bounce', 'anim-flash'];
|
|
428
440
|
for (const id of this.updatedIds) {
|
|
@@ -437,11 +449,6 @@ let BoardTileList = class BoardTileList extends LitElement {
|
|
|
437
449
|
}
|
|
438
450
|
}
|
|
439
451
|
}
|
|
440
|
-
onCreateBoard(e) {
|
|
441
|
-
this.dispatchEvent(new CustomEvent('create-board', {
|
|
442
|
-
detail: e.detail
|
|
443
|
-
}));
|
|
444
|
-
}
|
|
445
452
|
infoBoard(board) {
|
|
446
453
|
this.dispatchEvent(new CustomEvent('info-board', {
|
|
447
454
|
detail: board
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"board-tile-list.js","sourceRoot":"","sources":["../../client/board-list/board-tile-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\nimport '@operato/board/ox-board-creation-card.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, PropertyValues, nothing } from 'lit'\nimport { customElement, property, state, query } from 'lit/decorators.js'\nimport { repeat } from 'lit/directives/repeat.js'\n\nimport { client } from '@operato/graphql'\n\nimport { privileged } from '@things-factory/auth-base/dist-client/index.js'\n\n@customElement('board-tile-list')\nexport class BoardTileList extends LitElement {\n static styles = [\n css`\n :host {\n overflow: auto;\n padding: var(--popup-content-padding);\n display: grid;\n background-color: var(--md-sys-color-background);\n\n grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\n grid-auto-rows: var(--card-list-rows-height);\n grid-gap: 20px;\n }\n\n [card] {\n position: relative;\n align-items: center;\n overflow: hidden;\n }\n\n [card][create] {\n overflow: visible;\n background-color: initial;\n }\n\n [card] > a {\n display: flex;\n clip-path: border-box;\n }\n\n [card]:hover {\n cursor: pointer;\n }\n\n [name] {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n margin-top: var(--spacing-small);\n width: calc(100% - 45px);\n color: var(--md-sys-color-on-background);\n font-weight: bolder;\n font-size: var(--fontsize-small);\n }\n\n img {\n flex: 1;\n object-fit: contain;\n }\n\n md-icon[iconBtn] {\n float: right;\n margin-top: -20px;\n margin-left: 2px;\n color: var(--board-list-star-color);\n font-size: 1.4em;\n }\n md-icon[info] {\n color: var(--md-sys-color-primary);\n }\n\n md-icon[iconBtn][favored],\n md-icon[info]:hover {\n color: var(--board-list-star-active-color);\n }\n\n a {\n display: block;\n border-radius: var(--card-list-border-radius);\n border: var(--border-dim-color);\n box-sizing: border-box;\n color: var(--card-list-color);\n background-color: var(--card-list-background-color);\n margin: 0px;\n height: calc(100% - 25px);\n }\n\n :host > *:hover [info] {\n opacity: 1;\n -webkit-transition: opacity 0.8s;\n -moz-transition: opacity 0.8s;\n -o-transition: opacity 0.8s;\n transition: opacity 0.8s;\n }\n\n [draggable='true'] {\n cursor: grab;\n transition: opacity 0.2s ease, transform 0.2s ease;\n }\n\n [card].dragging {\n opacity: 0.3;\n transform: scale(0.95);\n }\n\n [card].drop-before {\n border-left: 3px solid var(--md-sys-color-primary);\n }\n\n [card].drop-after {\n border-right: 3px solid var(--md-sys-color-primary);\n }\n\n [card].flip-moving {\n transition: transform 1s cubic-bezier(0.25, 0.1, 0.25, 1);\n }\n\n @keyframes drop-land {\n 0% {\n opacity: 0;\n transform: scale(0.9);\n }\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n [card].flip-dropped-hidden {\n opacity: 0;\n }\n\n [card].flip-dropped {\n animation: drop-land 0.5s cubic-bezier(0.22, 0.6, 0.36, 1);\n }\n\n @keyframes highlight-sweep {\n 0% {\n background: linear-gradient(90deg, var(--md-sys-color-primary-container) 0%, transparent 0%);\n box-shadow: 0 0 8px 2px var(--md-sys-color-primary);\n }\n 50% {\n background: linear-gradient(90deg, transparent 0%, var(--md-sys-color-primary-container) 50%, transparent 100%);\n box-shadow: 0 0 12px 3px var(--md-sys-color-primary);\n }\n 100% {\n background: transparent;\n box-shadow: none;\n }\n }\n\n @keyframes border-pulse {\n 0%,\n 100% {\n outline: 2px solid transparent;\n }\n 25%,\n 75% {\n outline: 2px solid var(--md-sys-color-primary);\n }\n }\n\n @keyframes subtle-bounce {\n 0% {\n transform: scale(1);\n }\n 30% {\n transform: scale(1.03);\n }\n 100% {\n transform: scale(1);\n }\n }\n\n @keyframes surface-flash {\n 0% {\n background-color: var(--md-sys-color-primary-container);\n }\n 100% {\n background-color: transparent;\n }\n }\n\n [card].anim-sweep {\n animation: highlight-sweep 1.8s ease;\n border-radius: 4px;\n }\n\n [card].anim-pulse {\n animation: border-pulse 1.2s ease;\n }\n\n [card].anim-bounce {\n animation: subtle-bounce 0.8s ease;\n }\n\n [card].anim-flash {\n animation: surface-flash 1.5s ease-out;\n }\n\n @media screen and (max-width: 800px), screen and (max-height: 600px) {\n ox-board-creation-card {\n display: none;\n }\n }\n `\n ]\n\n @property({ type: Array }) boards: any[] = []\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Array }) groups: any[] = []\n @property({ type: String }) group?: string\n @property({ type: Boolean }) creatable?: boolean = false\n @property({ type: String, attribute: 'search-text' }) searchText?: string\n @property({ type: Boolean, attribute: 'reorderable' }) reorderable: boolean = false\n @property({ type: Array }) updatedIds: string[] = []\n\n private _draggedId: string | null = null\n private _dropTargetId: string | null = null\n private _dropSide: 'before' | 'after' | null = null\n\n connectedCallback() {\n super.connectedCallback()\n\n if (this.reorderable) {\n this.renderRoot.addEventListener('dragstart', (e: Event) => {\n const target = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n if (!target?.id) return\n\n this._draggedId = target.id\n target.classList.add('dragging')\n ;(e as DragEvent).dataTransfer!.effectAllowed = 'move'\n ;(e as DragEvent).dataTransfer?.setData('text/plain', target.id)\n })\n\n this.renderRoot.addEventListener('dragover', (e: Event) => {\n e.preventDefault()\n ;(e as DragEvent).dataTransfer!.dropEffect = 'move'\n\n const target = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n if (!target?.id || target.id === this._draggedId) return\n\n const targetRect = target.getBoundingClientRect()\n const mousePos = (e as DragEvent).clientX - targetRect.left\n const side = mousePos < targetRect.width / 2 ? 'before' : 'after'\n\n if (this._dropTargetId !== target.id || this._dropSide !== side) {\n this._clearDropIndicator()\n this._dropTargetId = target.id\n this._dropSide = side\n target.classList.add(side === 'before' ? 'drop-before' : 'drop-after')\n }\n })\n\n this.renderRoot.addEventListener('dragleave', (e: Event) => {\n const target = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n if (target?.id === this._dropTargetId) {\n const related = (e as DragEvent).relatedTarget as HTMLElement | null\n if (!related || !target.contains(related)) {\n this._clearDropIndicator()\n }\n }\n })\n\n this.renderRoot.addEventListener('drop', (e: Event) => {\n e.preventDefault()\n\n // drop 이벤트에서 직접 타겟과 방향을 계산 (dragleave가 먼저 발생해 상태를 지울 수 있으므로)\n const dropTarget = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n let dropTargetId = this._dropTargetId\n let dropSide = this._dropSide\n\n if (dropTarget?.id && dropTarget.id !== this._draggedId) {\n dropTargetId = dropTarget.id\n const rect = dropTarget.getBoundingClientRect()\n dropSide = (e as DragEvent).clientX - rect.left < rect.width / 2 ? 'before' : 'after'\n }\n\n this._clearDropIndicator()\n\n const draggedEl = this._draggedId ? this.renderRoot.querySelector(`[card][id=\"${this._draggedId}\"]`) : null\n if (draggedEl) {\n draggedEl.classList.remove('dragging')\n }\n\n if (!this._draggedId || !dropTargetId || this._draggedId === dropTargetId) {\n this._resetDragState()\n return\n }\n\n // 배열 재정렬\n const boards = [...this.boards]\n const draggedIndex = boards.findIndex(b => b.id === this._draggedId)\n if (draggedIndex === -1) {\n this._resetDragState()\n return\n }\n\n const draggedBoardId = this._draggedId\n const [dragged] = boards.splice(draggedIndex, 1)\n let targetIndex = boards.findIndex(b => b.id === dropTargetId)\n if (dropSide === 'after') targetIndex++\n boards.splice(targetIndex, 0, dragged)\n\n this._resetDragState()\n\n // FLIP 애니메이션: 이전 위치 기록\n const cards = this.renderRoot.querySelectorAll('[card][id]')\n const firstPositions = new Map<string, DOMRect>()\n cards.forEach(card => {\n firstPositions.set(card.id, card.getBoundingClientRect())\n })\n\n // optimistic update → Lit 렌더\n this.boards = boards\n\n this.updateComplete.then(() => {\n const updatedCards = this.renderRoot.querySelectorAll('[card][id]')\n let droppedEl: HTMLElement | null = null\n\n updatedCards.forEach(card => {\n const first = firstPositions.get(card.id)\n if (!first) return\n\n const last = card.getBoundingClientRect()\n const dx = first.left - last.left\n const dy = first.top - last.top\n\n const el = card as HTMLElement\n\n if (card.id === draggedBoardId) {\n // 드래그한 카드: 슬라이딩 완료 후 착지하도록 일단 숨김\n el.classList.add('flip-dropped-hidden')\n droppedEl = el\n } else {\n // 밀려나는 카드: 이전 위치에서 새 위치로 슬라이딩\n if (dx === 0 && dy === 0) return\n\n // Invert: 이전 위치로 되돌림\n el.style.transform = `translate(${dx}px, ${dy}px)`\n el.style.transition = 'none'\n\n requestAnimationFrame(() => {\n el.classList.add('flip-moving')\n el.style.transform = ''\n el.style.transition = ''\n\n el.addEventListener(\n 'transitionend',\n () => {\n el.classList.remove('flip-moving')\n },\n { once: true }\n )\n })\n }\n })\n\n // 밀려나는 카드 슬라이딩 완료 후 드래그한 카드 착지 → 착지 완료 후 이벤트 발송\n const boardIds = boards.map(b => b.id)\n const dispatchReordered = () => {\n this.dispatchEvent(\n new CustomEvent('reordered', {\n detail: {\n groupId: this.group,\n boardIds,\n movedId: draggedBoardId\n }\n })\n )\n }\n\n if (droppedEl) {\n setTimeout(() => {\n ;(droppedEl as HTMLElement).classList.remove('flip-dropped-hidden')\n ;(droppedEl as HTMLElement).classList.add('flip-dropped')\n ;(droppedEl as HTMLElement).addEventListener(\n 'animationend',\n () => {\n ;(droppedEl as HTMLElement).classList.remove('flip-dropped')\n dispatchReordered()\n },\n { once: true }\n )\n }, 500)\n } else {\n dispatchReordered()\n }\n })\n })\n\n this.renderRoot.addEventListener('dragend', (e: Event) => {\n this._clearDropIndicator()\n const target = (e.target as HTMLElement).closest('[card]')\n if (target) target.classList.remove('dragging')\n this._resetDragState()\n })\n }\n }\n\n private _clearDropIndicator() {\n if (this._dropTargetId) {\n const el = this.renderRoot.querySelector(`[card][id=\"${this._dropTargetId}\"]`)\n if (el) {\n el.classList.remove('drop-before', 'drop-after')\n }\n }\n this._dropTargetId = null\n this._dropSide = null\n }\n\n private _resetDragState() {\n this._draggedId = null\n this._dropTargetId = null\n this._dropSide = null\n }\n\n render() {\n const boards = this.boards || []\n\n return html`\n ${this.creatable\n ? privileged(\n { privilege: 'mutation', category: 'board' },\n html`\n <ox-board-creation-card\n .groups=${this.groups}\n .defaultGroup=${this.group}\n @create-board=${e => this.onCreateBoard(e)}\n card\n create\n ></ox-board-creation-card>\n `\n )\n : nothing}\n ${repeat(\n boards,\n board => board.id,\n board => html`\n <div card draggable=\"true\" id=${board.id}>\n <a href=\"board-viewer/${board.id}\"> <img src=${board.thumbnail} /> </a>\n\n <div name>${board.name}</div>\n <!-- <div description>${board.description}</div> -->\n\n <md-icon\n iconBtn\n info\n @click=${e => {\n this.infoBoard(board)\n e.preventDefault()\n }}\n >info</md-icon\n >\n\n ${(this.favorites || []).includes(board.id)\n ? html` <md-icon iconBtn favored @click=${e => this.removeFavorite(board.id)}>star</md-icon> `\n : html` <md-icon iconBtn @click=${e => this.addFavorite(board.id)}>star_border</md-icon> `}\n </div>\n `\n )}\n `\n }\n\n updated(changes: PropertyValues<this>) {\n const creationCard = this.renderRoot.querySelector('ox-board-creation-card') as any\n if (creationCard) {\n creationCard.reset()\n }\n\n if (changes.has('updatedIds') && this.updatedIds.length > 0) {\n const animClasses = ['anim-sweep', 'anim-pulse', 'anim-bounce', 'anim-flash']\n\n for (const id of this.updatedIds) {\n const card = this.renderRoot.querySelector(`[card][id=\"${id}\"]`)\n if (!card) continue\n\n const animClass = animClasses[Math.floor(Math.random() * animClasses.length)]\n card.classList.add(animClass)\n card.addEventListener(\n 'animationend',\n () => {\n card.classList.remove(animClass)\n },\n { once: true }\n )\n }\n }\n }\n\n onCreateBoard(e) {\n this.dispatchEvent(\n new CustomEvent('create-board', {\n detail: e.detail\n })\n )\n }\n\n infoBoard(board) {\n this.dispatchEvent(\n new CustomEvent('info-board', {\n detail: board\n })\n )\n }\n\n async removeFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n deleteFavorite(routing: \"${boardId}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n createFavorite(favorite: {\n routing: \"${boardId}\"\n }) {\n id\n routing\n }\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async refreshFavorites() {\n this.dispatchEvent(new CustomEvent('refresh-favorites'))\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"board-tile-list.js","sourceRoot":"","sources":["../../client/board-list/board-tile-list.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, PropertyValues, nothing } from 'lit'\nimport { customElement, property, state, query } from 'lit/decorators.js'\nimport { repeat } from 'lit/directives/repeat.js'\n\nimport { client } from '@operato/graphql'\nimport { i18next } from '@operato/i18n'\n\nimport { privileged } from '@things-factory/auth-base/dist-client/index.js'\n\n@customElement('board-tile-list')\nexport class BoardTileList extends LitElement {\n static styles = [\n css`\n :host {\n overflow: auto;\n padding: var(--popup-content-padding);\n display: grid;\n background-color: var(--md-sys-color-background);\n\n grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));\n grid-auto-rows: var(--card-list-rows-height);\n grid-gap: 20px;\n }\n\n [card] {\n position: relative;\n align-items: center;\n overflow: hidden;\n }\n\n [card][create] {\n overflow: visible;\n background-color: initial;\n }\n\n [card][import-card] > a {\n display: flex;\n align-items: center;\n justify-content: center;\n height: calc(100% - 25px);\n border: 1px dashed var(--md-sys-color-outline-variant, #b8c2cc);\n border-radius: var(--card-list-border-radius, 8px);\n text-decoration: none;\n color: var(--md-sys-color-on-secondary-container, #555);\n background: var(--md-sys-color-surface-container, #fff);\n box-sizing: border-box;\n }\n [card][import-card] > a:hover {\n border-color: var(--md-sys-color-primary, #2a64d8);\n color: var(--md-sys-color-primary, #2a64d8);\n background: var(--md-sys-color-primary-container, #eaf2ff);\n }\n [card][import-card] md-icon {\n font-size: 48px;\n --md-icon-size: 48px;\n }\n\n [card] > a {\n display: flex;\n clip-path: border-box;\n }\n\n [card]:hover {\n cursor: pointer;\n }\n\n [name] {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n margin-top: var(--spacing-small);\n width: calc(100% - 45px);\n color: var(--md-sys-color-on-background);\n font-weight: bolder;\n font-size: var(--fontsize-small);\n }\n\n img {\n flex: 1;\n object-fit: contain;\n }\n\n md-icon[iconBtn] {\n float: right;\n margin-top: -20px;\n margin-left: 2px;\n color: var(--board-list-star-color);\n font-size: 1.4em;\n }\n md-icon[info] {\n color: var(--md-sys-color-primary);\n }\n\n md-icon[iconBtn][favored],\n md-icon[info]:hover {\n color: var(--board-list-star-active-color);\n }\n\n a {\n display: block;\n border-radius: var(--card-list-border-radius);\n border: var(--border-dim-color);\n box-sizing: border-box;\n color: var(--card-list-color);\n background-color: var(--card-list-background-color);\n margin: 0px;\n height: calc(100% - 25px);\n }\n\n :host > *:hover [info] {\n opacity: 1;\n -webkit-transition: opacity 0.8s;\n -moz-transition: opacity 0.8s;\n -o-transition: opacity 0.8s;\n transition: opacity 0.8s;\n }\n\n [draggable='true'] {\n cursor: grab;\n transition: opacity 0.2s ease, transform 0.2s ease;\n }\n\n [card].dragging {\n opacity: 0.3;\n transform: scale(0.95);\n }\n\n [card].drop-before {\n border-left: 3px solid var(--md-sys-color-primary);\n }\n\n [card].drop-after {\n border-right: 3px solid var(--md-sys-color-primary);\n }\n\n [card].flip-moving {\n transition: transform 1s cubic-bezier(0.25, 0.1, 0.25, 1);\n }\n\n @keyframes drop-land {\n 0% {\n opacity: 0;\n transform: scale(0.9);\n }\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n }\n\n [card].flip-dropped-hidden {\n opacity: 0;\n }\n\n [card].flip-dropped {\n animation: drop-land 0.5s cubic-bezier(0.22, 0.6, 0.36, 1);\n }\n\n @keyframes highlight-sweep {\n 0% {\n background: linear-gradient(90deg, var(--md-sys-color-primary-container) 0%, transparent 0%);\n box-shadow: 0 0 8px 2px var(--md-sys-color-primary);\n }\n 50% {\n background: linear-gradient(90deg, transparent 0%, var(--md-sys-color-primary-container) 50%, transparent 100%);\n box-shadow: 0 0 12px 3px var(--md-sys-color-primary);\n }\n 100% {\n background: transparent;\n box-shadow: none;\n }\n }\n\n @keyframes border-pulse {\n 0%,\n 100% {\n outline: 2px solid transparent;\n }\n 25%,\n 75% {\n outline: 2px solid var(--md-sys-color-primary);\n }\n }\n\n @keyframes subtle-bounce {\n 0% {\n transform: scale(1);\n }\n 30% {\n transform: scale(1.03);\n }\n 100% {\n transform: scale(1);\n }\n }\n\n @keyframes surface-flash {\n 0% {\n background-color: var(--md-sys-color-primary-container);\n }\n 100% {\n background-color: transparent;\n }\n }\n\n [card].anim-sweep {\n animation: highlight-sweep 1.8s ease;\n border-radius: 4px;\n }\n\n [card].anim-pulse {\n animation: border-pulse 1.2s ease;\n }\n\n [card].anim-bounce {\n animation: subtle-bounce 0.8s ease;\n }\n\n [card].anim-flash {\n animation: surface-flash 1.5s ease-out;\n }\n\n `\n ]\n\n @property({ type: Array }) boards: any[] = []\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Array }) groups: any[] = []\n @property({ type: String }) group?: string\n @property({ type: Boolean }) creatable?: boolean = false\n @property({ type: String, attribute: 'search-text' }) searchText?: string\n @property({ type: Boolean, attribute: 'reorderable' }) reorderable: boolean = false\n @property({ type: Array }) updatedIds: string[] = []\n\n private _draggedId: string | null = null\n private _dropTargetId: string | null = null\n private _dropSide: 'before' | 'after' | null = null\n\n connectedCallback() {\n super.connectedCallback()\n\n if (this.reorderable) {\n this.renderRoot.addEventListener('dragstart', (e: Event) => {\n const target = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n if (!target?.id) return\n\n this._draggedId = target.id\n target.classList.add('dragging')\n ;(e as DragEvent).dataTransfer!.effectAllowed = 'move'\n ;(e as DragEvent).dataTransfer?.setData('text/plain', target.id)\n })\n\n this.renderRoot.addEventListener('dragover', (e: Event) => {\n e.preventDefault()\n ;(e as DragEvent).dataTransfer!.dropEffect = 'move'\n\n const target = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n if (!target?.id || target.id === this._draggedId) return\n\n const targetRect = target.getBoundingClientRect()\n const mousePos = (e as DragEvent).clientX - targetRect.left\n const side = mousePos < targetRect.width / 2 ? 'before' : 'after'\n\n if (this._dropTargetId !== target.id || this._dropSide !== side) {\n this._clearDropIndicator()\n this._dropTargetId = target.id\n this._dropSide = side\n target.classList.add(side === 'before' ? 'drop-before' : 'drop-after')\n }\n })\n\n this.renderRoot.addEventListener('dragleave', (e: Event) => {\n const target = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n if (target?.id === this._dropTargetId) {\n const related = (e as DragEvent).relatedTarget as HTMLElement | null\n if (!related || !target.contains(related)) {\n this._clearDropIndicator()\n }\n }\n })\n\n this.renderRoot.addEventListener('drop', (e: Event) => {\n e.preventDefault()\n\n // drop 이벤트에서 직접 타겟과 방향을 계산 (dragleave가 먼저 발생해 상태를 지울 수 있으므로)\n const dropTarget = (e.target as HTMLElement).closest('[card]') as HTMLElement | null\n let dropTargetId = this._dropTargetId\n let dropSide = this._dropSide\n\n if (dropTarget?.id && dropTarget.id !== this._draggedId) {\n dropTargetId = dropTarget.id\n const rect = dropTarget.getBoundingClientRect()\n dropSide = (e as DragEvent).clientX - rect.left < rect.width / 2 ? 'before' : 'after'\n }\n\n this._clearDropIndicator()\n\n const draggedEl = this._draggedId ? this.renderRoot.querySelector(`[card][id=\"${this._draggedId}\"]`) : null\n if (draggedEl) {\n draggedEl.classList.remove('dragging')\n }\n\n if (!this._draggedId || !dropTargetId || this._draggedId === dropTargetId) {\n this._resetDragState()\n return\n }\n\n // 배열 재정렬\n const boards = [...this.boards]\n const draggedIndex = boards.findIndex(b => b.id === this._draggedId)\n if (draggedIndex === -1) {\n this._resetDragState()\n return\n }\n\n const draggedBoardId = this._draggedId\n const [dragged] = boards.splice(draggedIndex, 1)\n let targetIndex = boards.findIndex(b => b.id === dropTargetId)\n if (dropSide === 'after') targetIndex++\n boards.splice(targetIndex, 0, dragged)\n\n this._resetDragState()\n\n // FLIP 애니메이션: 이전 위치 기록\n const cards = this.renderRoot.querySelectorAll('[card][id]')\n const firstPositions = new Map<string, DOMRect>()\n cards.forEach(card => {\n firstPositions.set(card.id, card.getBoundingClientRect())\n })\n\n // optimistic update → Lit 렌더\n this.boards = boards\n\n this.updateComplete.then(() => {\n const updatedCards = this.renderRoot.querySelectorAll('[card][id]')\n let droppedEl: HTMLElement | null = null\n\n updatedCards.forEach(card => {\n const first = firstPositions.get(card.id)\n if (!first) return\n\n const last = card.getBoundingClientRect()\n const dx = first.left - last.left\n const dy = first.top - last.top\n\n const el = card as HTMLElement\n\n if (card.id === draggedBoardId) {\n // 드래그한 카드: 슬라이딩 완료 후 착지하도록 일단 숨김\n el.classList.add('flip-dropped-hidden')\n droppedEl = el\n } else {\n // 밀려나는 카드: 이전 위치에서 새 위치로 슬라이딩\n if (dx === 0 && dy === 0) return\n\n // Invert: 이전 위치로 되돌림\n el.style.transform = `translate(${dx}px, ${dy}px)`\n el.style.transition = 'none'\n\n requestAnimationFrame(() => {\n el.classList.add('flip-moving')\n el.style.transform = ''\n el.style.transition = ''\n\n el.addEventListener(\n 'transitionend',\n () => {\n el.classList.remove('flip-moving')\n },\n { once: true }\n )\n })\n }\n })\n\n // 밀려나는 카드 슬라이딩 완료 후 드래그한 카드 착지 → 착지 완료 후 이벤트 발송\n const boardIds = boards.map(b => b.id)\n const dispatchReordered = () => {\n this.dispatchEvent(\n new CustomEvent('reordered', {\n detail: {\n groupId: this.group,\n boardIds,\n movedId: draggedBoardId\n }\n })\n )\n }\n\n if (droppedEl) {\n setTimeout(() => {\n ;(droppedEl as HTMLElement).classList.remove('flip-dropped-hidden')\n ;(droppedEl as HTMLElement).classList.add('flip-dropped')\n ;(droppedEl as HTMLElement).addEventListener(\n 'animationend',\n () => {\n ;(droppedEl as HTMLElement).classList.remove('flip-dropped')\n dispatchReordered()\n },\n { once: true }\n )\n }, 500)\n } else {\n dispatchReordered()\n }\n })\n })\n\n this.renderRoot.addEventListener('dragend', (e: Event) => {\n this._clearDropIndicator()\n const target = (e.target as HTMLElement).closest('[card]')\n if (target) target.classList.remove('dragging')\n this._resetDragState()\n })\n }\n }\n\n private _clearDropIndicator() {\n if (this._dropTargetId) {\n const el = this.renderRoot.querySelector(`[card][id=\"${this._dropTargetId}\"]`)\n if (el) {\n el.classList.remove('drop-before', 'drop-after')\n }\n }\n this._dropTargetId = null\n this._dropSide = null\n }\n\n private _resetDragState() {\n this._draggedId = null\n this._dropTargetId = null\n this._dropSide = null\n }\n\n render() {\n const boards = this.boards || []\n\n return html`\n ${this.creatable\n ? privileged(\n { privilege: 'mutation', category: 'board' },\n html`\n <div card import-card>\n <a href=\"board-create\" title=${i18next.t('text.create board') || 'Create New Board'}>\n <md-icon>add_circle_outline</md-icon>\n </a>\n <div name>${i18next.t('label.create board') || 'Create Board'}</div>\n </div>\n `\n )\n : nothing}\n ${repeat(\n boards,\n board => board.id,\n board => html`\n <div card draggable=\"true\" id=${board.id}>\n <a href=\"board-viewer/${board.id}\"> <img src=${board.thumbnail} /> </a>\n\n <div name>${board.name}</div>\n <!-- <div description>${board.description}</div> -->\n\n <md-icon\n iconBtn\n info\n @click=${e => {\n this.infoBoard(board)\n e.preventDefault()\n }}\n >info</md-icon\n >\n\n ${(this.favorites || []).includes(board.id)\n ? html` <md-icon iconBtn favored @click=${e => this.removeFavorite(board.id)}>star</md-icon> `\n : html` <md-icon iconBtn @click=${e => this.addFavorite(board.id)}>star_border</md-icon> `}\n </div>\n `\n )}\n `\n }\n\n updated(changes: PropertyValues<this>) {\n if (changes.has('updatedIds') && this.updatedIds.length > 0) {\n const animClasses = ['anim-sweep', 'anim-pulse', 'anim-bounce', 'anim-flash']\n\n for (const id of this.updatedIds) {\n const card = this.renderRoot.querySelector(`[card][id=\"${id}\"]`)\n if (!card) continue\n\n const animClass = animClasses[Math.floor(Math.random() * animClasses.length)]\n card.classList.add(animClass)\n card.addEventListener(\n 'animationend',\n () => {\n card.classList.remove(animClass)\n },\n { once: true }\n )\n }\n }\n }\n\n infoBoard(board) {\n this.dispatchEvent(\n new CustomEvent('info-board', {\n detail: board\n })\n )\n }\n\n async removeFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n deleteFavorite(routing: \"${boardId}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(boardId) {\n await client.mutate({\n mutation: gql`\n mutation {\n createFavorite(favorite: {\n routing: \"${boardId}\"\n }) {\n id\n routing\n }\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async refreshFavorites() {\n this.dispatchEvent(new CustomEvent('refresh-favorites'))\n }\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface AttachmentResult {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
mimetype?: string;
|
|
5
|
+
size?: number;
|
|
6
|
+
path?: string;
|
|
7
|
+
category?: string;
|
|
8
|
+
createdAt?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 단일 파일을 Attachment 로 등록 — graphql-upload (Apollo client multipart) 사용.
|
|
12
|
+
* file 은 Browser File 객체. 결과로 새 Attachment id / 메타데이터 반환.
|
|
13
|
+
*
|
|
14
|
+
* board-import wizard 가 사용 — 이후 importBoardAsync(attachmentId=result.id) 로 변환 시작.
|
|
15
|
+
*/
|
|
16
|
+
export declare function createAttachmentForImport(file: File): Promise<AttachmentResult>;
|
|
17
|
+
/**
|
|
18
|
+
* 기존 attachment 목록 조회 — wizard upload 스텝의 "기존 파일 선택" 탭에서 사용.
|
|
19
|
+
* 도메인 스코프 내 attachment 만 반환되는 건 attachment-base resolver 가 보장.
|
|
20
|
+
*
|
|
21
|
+
* @param search 파일명 부분 일치 (선택)
|
|
22
|
+
* @param mimetypePrefix 'image' | 'application' 등 — wizard 는 이미지/dxf 만 보여주려고 사용
|
|
23
|
+
* @param page / limit 페이지네이션 (기본 1, 50)
|
|
24
|
+
*/
|
|
25
|
+
export declare function fetchAttachmentsForImport(options: {
|
|
26
|
+
search?: string;
|
|
27
|
+
mimetypePrefix?: string;
|
|
28
|
+
page?: number;
|
|
29
|
+
limit?: number;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
items: AttachmentResult[];
|
|
32
|
+
total: number;
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attachment GraphQL operations — board-import wizard 가 도면 파일 업로드 시 사용.
|
|
3
|
+
*
|
|
4
|
+
* 백엔드: @things-factory/attachment-base 의 createAttachment mutation.
|
|
5
|
+
* 별도 ox-attachment-list 의 흐름과 독립 — wizard 는 단순 file input → createAttachment
|
|
6
|
+
* → attachmentId 획득 → importBoardAsync 로 전달하는 짧은 흐름만 필요.
|
|
7
|
+
*/
|
|
8
|
+
import gql from 'graphql-tag';
|
|
9
|
+
import { client } from '@operato/graphql';
|
|
10
|
+
/**
|
|
11
|
+
* 단일 파일을 Attachment 로 등록 — graphql-upload (Apollo client multipart) 사용.
|
|
12
|
+
* file 은 Browser File 객체. 결과로 새 Attachment id / 메타데이터 반환.
|
|
13
|
+
*
|
|
14
|
+
* board-import wizard 가 사용 — 이후 importBoardAsync(attachmentId=result.id) 로 변환 시작.
|
|
15
|
+
*/
|
|
16
|
+
export async function createAttachmentForImport(file) {
|
|
17
|
+
const response = await client.mutate({
|
|
18
|
+
mutation: gql `
|
|
19
|
+
mutation CreateAttachmentForImport($attachment: NewAttachment!) {
|
|
20
|
+
createAttachment(attachment: $attachment) {
|
|
21
|
+
id
|
|
22
|
+
name
|
|
23
|
+
mimetype
|
|
24
|
+
size
|
|
25
|
+
path
|
|
26
|
+
category
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
`,
|
|
30
|
+
variables: {
|
|
31
|
+
attachment: {
|
|
32
|
+
file,
|
|
33
|
+
category: 'import',
|
|
34
|
+
refType: 'board-import',
|
|
35
|
+
description: 'board-import wizard upload'
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
// multipart 업로드는 Apollo upload-link 가 처리. fetchPolicy 강제 무관.
|
|
39
|
+
context: {
|
|
40
|
+
hasUpload: true
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return response.data.createAttachment;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 기존 attachment 목록 조회 — wizard upload 스텝의 "기존 파일 선택" 탭에서 사용.
|
|
47
|
+
* 도메인 스코프 내 attachment 만 반환되는 건 attachment-base resolver 가 보장.
|
|
48
|
+
*
|
|
49
|
+
* @param search 파일명 부분 일치 (선택)
|
|
50
|
+
* @param mimetypePrefix 'image' | 'application' 등 — wizard 는 이미지/dxf 만 보여주려고 사용
|
|
51
|
+
* @param page / limit 페이지네이션 (기본 1, 50)
|
|
52
|
+
*/
|
|
53
|
+
export async function fetchAttachmentsForImport(options) {
|
|
54
|
+
const filters = [];
|
|
55
|
+
if (options.search) {
|
|
56
|
+
filters.push({ name: 'name', operator: 'i_like', value: `%${options.search}%` });
|
|
57
|
+
}
|
|
58
|
+
if (options.mimetypePrefix) {
|
|
59
|
+
filters.push({ name: 'mimetype', operator: 'i_like', value: `${options.mimetypePrefix}%` });
|
|
60
|
+
}
|
|
61
|
+
const response = await client.query({
|
|
62
|
+
query: gql `
|
|
63
|
+
query AttachmentsForImport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {
|
|
64
|
+
attachments(filters: $filters, pagination: $pagination, sortings: $sortings) {
|
|
65
|
+
items {
|
|
66
|
+
id
|
|
67
|
+
name
|
|
68
|
+
mimetype
|
|
69
|
+
size
|
|
70
|
+
path
|
|
71
|
+
category
|
|
72
|
+
createdAt
|
|
73
|
+
}
|
|
74
|
+
total
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
`,
|
|
78
|
+
variables: {
|
|
79
|
+
filters,
|
|
80
|
+
pagination: { page: options.page ?? 1, limit: options.limit ?? 50 },
|
|
81
|
+
sortings: [{ name: 'createdAt', desc: true }]
|
|
82
|
+
},
|
|
83
|
+
fetchPolicy: 'no-cache'
|
|
84
|
+
});
|
|
85
|
+
return response.data.attachments;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=attachment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../client/graphql/attachment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAYzC;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,IAAU;IACxD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;;KAWZ;QACD,SAAS,EAAE;YACT,UAAU,EAAE;gBACV,IAAI;gBACJ,QAAQ,EAAE,QAAQ;gBAClB,OAAO,EAAE,cAAc;gBACvB,WAAW,EAAE,4BAA4B;aAC1C;SACF;QACD,6DAA6D;QAC7D,OAAO,EAAE;YACP,SAAS,EAAE,IAAI;SAChB;KACF,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAA;AACvC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAAC,OAK/C;IACC,MAAM,OAAO,GAA6D,EAAE,CAAA;IAC5E,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAClF,CAAC;IACD,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;QAC3B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,cAAc,GAAG,EAAE,CAAC,CAAA;IAC7F,CAAC;IACD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;;;;;;;;;KAeT;QACD,SAAS,EAAE;YACT,OAAO;YACP,UAAU,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE;YACnE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;SAC9C;QACD,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAA;AAClC,CAAC","sourcesContent":["/**\n * Attachment GraphQL operations — board-import wizard 가 도면 파일 업로드 시 사용.\n *\n * 백엔드: @things-factory/attachment-base 의 createAttachment mutation.\n * 별도 ox-attachment-list 의 흐름과 독립 — wizard 는 단순 file input → createAttachment\n * → attachmentId 획득 → importBoardAsync 로 전달하는 짧은 흐름만 필요.\n */\nimport gql from 'graphql-tag'\n\nimport { client } from '@operato/graphql'\n\nexport interface AttachmentResult {\n id: string\n name: string\n mimetype?: string\n size?: number\n path?: string\n category?: string\n createdAt?: string\n}\n\n/**\n * 단일 파일을 Attachment 로 등록 — graphql-upload (Apollo client multipart) 사용.\n * file 은 Browser File 객체. 결과로 새 Attachment id / 메타데이터 반환.\n *\n * board-import wizard 가 사용 — 이후 importBoardAsync(attachmentId=result.id) 로 변환 시작.\n */\nexport async function createAttachmentForImport(file: File): Promise<AttachmentResult> {\n const response = await client.mutate({\n mutation: gql`\n mutation CreateAttachmentForImport($attachment: NewAttachment!) {\n createAttachment(attachment: $attachment) {\n id\n name\n mimetype\n size\n path\n category\n }\n }\n `,\n variables: {\n attachment: {\n file,\n category: 'import',\n refType: 'board-import',\n description: 'board-import wizard upload'\n }\n },\n // multipart 업로드는 Apollo upload-link 가 처리. fetchPolicy 강제 무관.\n context: {\n hasUpload: true\n }\n })\n return response.data.createAttachment\n}\n\n/**\n * 기존 attachment 목록 조회 — wizard upload 스텝의 \"기존 파일 선택\" 탭에서 사용.\n * 도메인 스코프 내 attachment 만 반환되는 건 attachment-base resolver 가 보장.\n *\n * @param search 파일명 부분 일치 (선택)\n * @param mimetypePrefix 'image' | 'application' 등 — wizard 는 이미지/dxf 만 보여주려고 사용\n * @param page / limit 페이지네이션 (기본 1, 50)\n */\nexport async function fetchAttachmentsForImport(options: {\n search?: string\n mimetypePrefix?: string\n page?: number\n limit?: number\n}): Promise<{ items: AttachmentResult[]; total: number }> {\n const filters: Array<{ name: string; operator: string; value: string }> = []\n if (options.search) {\n filters.push({ name: 'name', operator: 'i_like', value: `%${options.search}%` })\n }\n if (options.mimetypePrefix) {\n filters.push({ name: 'mimetype', operator: 'i_like', value: `${options.mimetypePrefix}%` })\n }\n const response = await client.query({\n query: gql`\n query AttachmentsForImport($filters: [Filter!], $pagination: Pagination, $sortings: [Sorting!]) {\n attachments(filters: $filters, pagination: $pagination, sortings: $sortings) {\n items {\n id\n name\n mimetype\n size\n path\n category\n createdAt\n }\n total\n }\n }\n `,\n variables: {\n filters,\n pagination: { page: options.page ?? 1, limit: options.limit ?? 50 },\n sortings: [{ name: 'createdAt', desc: true }]\n },\n fetchPolicy: 'no-cache'\n })\n return response.data.attachments\n}\n"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface ImportBoardAsyncInput {
|
|
2
|
+
attachmentId: string;
|
|
3
|
+
chatSessionId?: string;
|
|
4
|
+
scopes?: string[];
|
|
5
|
+
normalizeOrigin?: boolean;
|
|
6
|
+
flipY?: boolean;
|
|
7
|
+
scale?: number;
|
|
8
|
+
applyBinding?: boolean;
|
|
9
|
+
parseOptions?: any;
|
|
10
|
+
/**
|
|
11
|
+
* 사용자 자유서술 hint — 도면 설명 / 강조 부분 / 카테고리 가이드 등.
|
|
12
|
+
* VLM 의 view type 분류 + entity 추출에 추가 컨텍스트로 합류.
|
|
13
|
+
*/
|
|
14
|
+
userPrompt?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function importBoardAsync(input: ImportBoardAsyncInput): Promise<any>;
|
|
17
|
+
export declare function fetchImportSession(id: string): Promise<any>;
|
|
18
|
+
export interface MaterializeImportSessionInput {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description?: string;
|
|
22
|
+
groupId?: string;
|
|
23
|
+
type?: 'main' | 'sub' | 'popup';
|
|
24
|
+
thumbnail?: string;
|
|
25
|
+
/** 선택한 시안 id ('as-is' / 'scene' / 'auto-fit' 등). 미지정 시 default. */
|
|
26
|
+
variantId?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 충돌하지 않는 새 Board 의 짧은 이름 + 자세한 description 제안.
|
|
30
|
+
* 서버가 hint / userPrompt / AI importStrategy / 카테고리 분포 등을 합성해
|
|
31
|
+
* 둘 다 만들어준다. 클라이언트는 review 진입 시 한 번 호출.
|
|
32
|
+
*/
|
|
33
|
+
export declare function suggestBoardMeta(input: {
|
|
34
|
+
sessionId?: string;
|
|
35
|
+
hint?: string;
|
|
36
|
+
}): Promise<{
|
|
37
|
+
name: string;
|
|
38
|
+
description: string;
|
|
39
|
+
}>;
|
|
40
|
+
/** @deprecated suggestBoardMeta 사용. name 만 필요한 구버전 호출처 호환용. */
|
|
41
|
+
export declare function suggestBoardName(input: {
|
|
42
|
+
sessionId?: string;
|
|
43
|
+
hint?: string;
|
|
44
|
+
}): Promise<string>;
|
|
45
|
+
export declare function materializeImportSession(input: MaterializeImportSessionInput): Promise<any>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* board-import GraphQL operation client — wizard page 가 사용.
|
|
3
|
+
*
|
|
4
|
+
* 백엔드 정의: @things-factory/board-import 의 ImportSessionResolver.
|
|
5
|
+
* - importBoardAsync(input: ImportBoardAsyncInput!): ImportSession
|
|
6
|
+
* - importSession(id: String!): ImportSession
|
|
7
|
+
* - materializeImportSession(input: MaterializeImportSessionInput!): Board
|
|
8
|
+
*/
|
|
9
|
+
import gql from 'graphql-tag';
|
|
10
|
+
import { client } from '@operato/graphql';
|
|
11
|
+
const IMPORT_SESSION_FIELDS = `
|
|
12
|
+
id
|
|
13
|
+
status
|
|
14
|
+
progress
|
|
15
|
+
message
|
|
16
|
+
totalEntities
|
|
17
|
+
options
|
|
18
|
+
result
|
|
19
|
+
attachmentId
|
|
20
|
+
chatSessionId
|
|
21
|
+
createdAt
|
|
22
|
+
updatedAt
|
|
23
|
+
completedAt
|
|
24
|
+
`;
|
|
25
|
+
export async function importBoardAsync(input) {
|
|
26
|
+
const response = await client.mutate({
|
|
27
|
+
mutation: gql `
|
|
28
|
+
mutation ImportBoardAsync($input: ImportBoardAsyncInput!) {
|
|
29
|
+
importBoardAsync(input: $input) {
|
|
30
|
+
${IMPORT_SESSION_FIELDS}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
`,
|
|
34
|
+
variables: { input }
|
|
35
|
+
});
|
|
36
|
+
return response.data?.importBoardAsync;
|
|
37
|
+
}
|
|
38
|
+
export async function fetchImportSession(id) {
|
|
39
|
+
const response = await client.query({
|
|
40
|
+
query: gql `
|
|
41
|
+
query ImportSession($id: String!) {
|
|
42
|
+
importSession(id: $id) {
|
|
43
|
+
${IMPORT_SESSION_FIELDS}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
`,
|
|
47
|
+
variables: { id },
|
|
48
|
+
// polling 시 cache 우회 — 매 호출마다 server fresh.
|
|
49
|
+
fetchPolicy: 'no-cache'
|
|
50
|
+
});
|
|
51
|
+
return response.data?.importSession;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 충돌하지 않는 새 Board 의 짧은 이름 + 자세한 description 제안.
|
|
55
|
+
* 서버가 hint / userPrompt / AI importStrategy / 카테고리 분포 등을 합성해
|
|
56
|
+
* 둘 다 만들어준다. 클라이언트는 review 진입 시 한 번 호출.
|
|
57
|
+
*/
|
|
58
|
+
export async function suggestBoardMeta(input) {
|
|
59
|
+
const response = await client.query({
|
|
60
|
+
query: gql `
|
|
61
|
+
query SuggestBoardMeta($input: SuggestBoardNameInput!) {
|
|
62
|
+
suggestBoardMeta(input: $input) {
|
|
63
|
+
name
|
|
64
|
+
description
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
`,
|
|
68
|
+
variables: { input },
|
|
69
|
+
fetchPolicy: 'no-cache'
|
|
70
|
+
});
|
|
71
|
+
return response.data?.suggestBoardMeta ?? { name: '', description: '' };
|
|
72
|
+
}
|
|
73
|
+
/** @deprecated suggestBoardMeta 사용. name 만 필요한 구버전 호출처 호환용. */
|
|
74
|
+
export async function suggestBoardName(input) {
|
|
75
|
+
const response = await client.query({
|
|
76
|
+
query: gql `
|
|
77
|
+
query SuggestBoardName($input: SuggestBoardNameInput!) {
|
|
78
|
+
suggestBoardName(input: $input)
|
|
79
|
+
}
|
|
80
|
+
`,
|
|
81
|
+
variables: { input },
|
|
82
|
+
fetchPolicy: 'no-cache'
|
|
83
|
+
});
|
|
84
|
+
return response.data?.suggestBoardName ?? '';
|
|
85
|
+
}
|
|
86
|
+
export async function materializeImportSession(input) {
|
|
87
|
+
const response = await client.mutate({
|
|
88
|
+
mutation: gql `
|
|
89
|
+
mutation MaterializeImportSession($input: MaterializeImportSessionInput!) {
|
|
90
|
+
materializeImportSession(input: $input) {
|
|
91
|
+
id
|
|
92
|
+
name
|
|
93
|
+
description
|
|
94
|
+
state
|
|
95
|
+
sourceImportSessionId
|
|
96
|
+
createdAt
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
`,
|
|
100
|
+
variables: { input }
|
|
101
|
+
});
|
|
102
|
+
return response.data?.materializeImportSession;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=board-import.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board-import.js","sourceRoot":"","sources":["../../client/graphql/board-import.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;CAa7B,CAAA;AAkBD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAA4B;IACjE,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;YAGL,qBAAqB;;;KAG5B;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;KACrB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAA;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAU;IACjD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;YAGF,qBAAqB;;;KAG5B;QACD,SAAS,EAAE,EAAE,EAAE,EAAE;QACjB,4CAA4C;QAC5C,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;AACrC,CAAC;AAaD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAGtC;IACC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;KAOT;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;QACpB,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,gBAAgB,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAA;AACzE,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAGtC;IACC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;QAClC,KAAK,EAAE,GAAG,CAAA;;;;KAIT;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;QACpB,WAAW,EAAE,UAAU;KACxB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,gBAAgB,IAAI,EAAE,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,KAAoC;IACjF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;QACnC,QAAQ,EAAE,GAAG,CAAA;;;;;;;;;;;KAWZ;QACD,SAAS,EAAE,EAAE,KAAK,EAAE;KACrB,CAAC,CAAA;IACF,OAAO,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAA;AAChD,CAAC","sourcesContent":["/**\n * board-import GraphQL operation client — wizard page 가 사용.\n *\n * 백엔드 정의: @things-factory/board-import 의 ImportSessionResolver.\n * - importBoardAsync(input: ImportBoardAsyncInput!): ImportSession\n * - importSession(id: String!): ImportSession\n * - materializeImportSession(input: MaterializeImportSessionInput!): Board\n */\nimport gql from 'graphql-tag'\n\nimport { client } from '@operato/graphql'\n\nconst IMPORT_SESSION_FIELDS = `\n id\n status\n progress\n message\n totalEntities\n options\n result\n attachmentId\n chatSessionId\n createdAt\n updatedAt\n completedAt\n`\n\nexport interface ImportBoardAsyncInput {\n attachmentId: string\n chatSessionId?: string\n scopes?: string[]\n normalizeOrigin?: boolean\n flipY?: boolean\n scale?: number\n applyBinding?: boolean\n parseOptions?: any\n /**\n * 사용자 자유서술 hint — 도면 설명 / 강조 부분 / 카테고리 가이드 등.\n * VLM 의 view type 분류 + entity 추출에 추가 컨텍스트로 합류.\n */\n userPrompt?: string\n}\n\nexport async function importBoardAsync(input: ImportBoardAsyncInput) {\n const response = await client.mutate({\n mutation: gql`\n mutation ImportBoardAsync($input: ImportBoardAsyncInput!) {\n importBoardAsync(input: $input) {\n ${IMPORT_SESSION_FIELDS}\n }\n }\n `,\n variables: { input }\n })\n return response.data?.importBoardAsync\n}\n\nexport async function fetchImportSession(id: string) {\n const response = await client.query({\n query: gql`\n query ImportSession($id: String!) {\n importSession(id: $id) {\n ${IMPORT_SESSION_FIELDS}\n }\n }\n `,\n variables: { id },\n // polling 시 cache 우회 — 매 호출마다 server fresh.\n fetchPolicy: 'no-cache'\n })\n return response.data?.importSession\n}\n\nexport interface MaterializeImportSessionInput {\n sessionId: string\n name: string\n description?: string\n groupId?: string\n type?: 'main' | 'sub' | 'popup'\n thumbnail?: string\n /** 선택한 시안 id ('as-is' / 'scene' / 'auto-fit' 등). 미지정 시 default. */\n variantId?: string\n}\n\n/**\n * 충돌하지 않는 새 Board 의 짧은 이름 + 자세한 description 제안.\n * 서버가 hint / userPrompt / AI importStrategy / 카테고리 분포 등을 합성해\n * 둘 다 만들어준다. 클라이언트는 review 진입 시 한 번 호출.\n */\nexport async function suggestBoardMeta(input: {\n sessionId?: string\n hint?: string\n}): Promise<{ name: string; description: string }> {\n const response = await client.query({\n query: gql`\n query SuggestBoardMeta($input: SuggestBoardNameInput!) {\n suggestBoardMeta(input: $input) {\n name\n description\n }\n }\n `,\n variables: { input },\n fetchPolicy: 'no-cache'\n })\n return response.data?.suggestBoardMeta ?? { name: '', description: '' }\n}\n\n/** @deprecated suggestBoardMeta 사용. name 만 필요한 구버전 호출처 호환용. */\nexport async function suggestBoardName(input: {\n sessionId?: string\n hint?: string\n}): Promise<string> {\n const response = await client.query({\n query: gql`\n query SuggestBoardName($input: SuggestBoardNameInput!) {\n suggestBoardName(input: $input)\n }\n `,\n variables: { input },\n fetchPolicy: 'no-cache'\n })\n return response.data?.suggestBoardName ?? ''\n}\n\nexport async function materializeImportSession(input: MaterializeImportSessionInput) {\n const response = await client.mutate({\n mutation: gql`\n mutation MaterializeImportSession($input: MaterializeImportSessionInput!) {\n materializeImportSession(input: $input) {\n id\n name\n description\n state\n sourceImportSessionId\n createdAt\n }\n }\n `,\n variables: { input }\n })\n return response.data?.materializeImportSession\n}\n"]}
|