@things-factory/board-ui 10.0.0-beta.3 → 10.0.0-beta.30

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.
Files changed (60) hide show
  1. package/dist-client/apptools/favorite-tool.js +5 -5
  2. package/dist-client/apptools/favorite-tool.js.map +1 -1
  3. package/dist-client/board-list/board-tile-list.d.ts +6 -1
  4. package/dist-client/board-list/board-tile-list.js +290 -44
  5. package/dist-client/board-list/board-tile-list.js.map +1 -1
  6. package/dist-client/board-list/group-bar.js +3 -3
  7. package/dist-client/board-list/group-bar.js.map +1 -1
  8. package/dist-client/board-list/play-group-bar.d.ts +0 -1
  9. package/dist-client/board-list/play-group-bar.js +3 -6
  10. package/dist-client/board-list/play-group-bar.js.map +1 -1
  11. package/dist-client/board-provider.js +20 -7
  12. package/dist-client/board-provider.js.map +1 -1
  13. package/dist-client/data-grist/board-editor.js +4 -4
  14. package/dist-client/data-grist/board-editor.js.map +1 -1
  15. package/dist-client/data-grist/board-renderer.js +4 -4
  16. package/dist-client/data-grist/board-renderer.js.map +1 -1
  17. package/dist-client/graphql/board-template.js +1 -1
  18. package/dist-client/graphql/board-template.js.map +1 -1
  19. package/dist-client/graphql/board.d.ts +1 -0
  20. package/dist-client/graphql/board.js +27 -2
  21. package/dist-client/graphql/board.js.map +1 -1
  22. package/dist-client/graphql/group.js +1 -1
  23. package/dist-client/graphql/group.js.map +1 -1
  24. package/dist-client/graphql/play-group.js +3 -3
  25. package/dist-client/graphql/play-group.js.map +1 -1
  26. package/dist-client/pages/board-list-page.d.ts +12 -0
  27. package/dist-client/pages/board-list-page.js +101 -19
  28. package/dist-client/pages/board-list-page.js.map +1 -1
  29. package/dist-client/pages/board-modeller-page.d.ts +1 -0
  30. package/dist-client/pages/board-modeller-page.js +20 -9
  31. package/dist-client/pages/board-modeller-page.js.map +1 -1
  32. package/dist-client/pages/board-player-by-name-page.js.map +1 -1
  33. package/dist-client/pages/board-player-page.js +2 -2
  34. package/dist-client/pages/board-player-page.js.map +1 -1
  35. package/dist-client/pages/board-viewer-by-name-page.d.ts +8 -1
  36. package/dist-client/pages/board-viewer-by-name-page.js +9 -1
  37. package/dist-client/pages/board-viewer-by-name-page.js.map +1 -1
  38. package/dist-client/pages/board-viewer-page.d.ts +2 -1
  39. package/dist-client/pages/board-viewer-page.js +42 -25
  40. package/dist-client/pages/board-viewer-page.js.map +1 -1
  41. package/dist-client/pages/play-list-page.js +11 -10
  42. package/dist-client/pages/play-list-page.js.map +1 -1
  43. package/dist-client/pages/printable-board-viewer-page.js +2 -2
  44. package/dist-client/pages/printable-board-viewer-page.js.map +1 -1
  45. package/dist-client/pages/theme/theme-editors.d.ts +1 -1
  46. package/dist-client/tsconfig.tsbuildinfo +1 -1
  47. package/dist-client/viewparts/board-basic-info.js +7 -7
  48. package/dist-client/viewparts/board-basic-info.js.map +1 -1
  49. package/dist-client/viewparts/board-versions.js +1 -1
  50. package/dist-client/viewparts/board-versions.js.map +1 -1
  51. package/dist-client/viewparts/group-info-basic.js +2 -2
  52. package/dist-client/viewparts/group-info-basic.js.map +1 -1
  53. package/dist-client/viewparts/group-info-import.js +2 -2
  54. package/dist-client/viewparts/group-info-import.js.map +1 -1
  55. package/dist-client/viewparts/link-builder.js +1 -1
  56. package/dist-client/viewparts/link-builder.js.map +1 -1
  57. package/dist-client/viewparts/play-group-info-basic.js +2 -2
  58. package/dist-client/viewparts/play-group-info-basic.js.map +1 -1
  59. package/dist-server/tsconfig.tsbuildinfo +1 -1
  60. package/package.json +5 -5
@@ -24,7 +24,7 @@ let FavoriteTool = class FavoriteTool extends LitElement {
24
24
  }
25
25
  `; }
26
26
  render() {
27
- var renderable = (this.acceptedPages || []).indexOf(this.page) !== -1;
27
+ const renderable = (this.acceptedPages || []).indexOf(this.page) !== -1;
28
28
  return renderable
29
29
  ? html `
30
30
  <md-icon @click=${this.onClick.bind(this)} ?favorable=${!this.favored}
@@ -86,8 +86,8 @@ let FavoriteTool = class FavoriteTool extends LitElement {
86
86
  });
87
87
  }
88
88
  async removeFavorite(routing) {
89
- await client.query({
90
- query: gql `
89
+ await client.mutate({
90
+ mutation: gql `
91
91
  mutation {
92
92
  deleteFavorite(routing: "${routing}")
93
93
  }
@@ -96,8 +96,8 @@ let FavoriteTool = class FavoriteTool extends LitElement {
96
96
  this.refreshFavorites();
97
97
  }
98
98
  async addFavorite(routing) {
99
- await client.query({
100
- query: gql `
99
+ await client.mutate({
100
+ mutation: gql `
101
101
  mutation {
102
102
  createFavorite(favorite: {
103
103
  routing: "${routing}"
@@ -1 +1 @@
1
- {"version":3,"file":"favorite-tool.js","sourceRoot":"","sources":["../../client/apptools/favorite-tool.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AAEnC,OAAO,GAAG,MAAM,aAAa,CAAA;AAC7B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAA;AAGpE,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,UAAU;IAArC;;QAasB,cAAS,GAAU,EAAE,CAAA;QAIrB,kBAAa,GAAU,EAAE,CAAA;IAuHtD,CAAC;aAvIQ,WAAM,GAAG,GAAG,CAAA;;;;;;;;;;GAUlB,AAVY,CAUZ;IAUD,MAAM;QACJ,IAAI,UAAU,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAErE,OAAO,UAAU;YACf,CAAC,CAAC,IAAI,CAAA;4BACgB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO;eAChE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa;;SAE3C;YACH,CAAC,CAAC,OAAO,CAAA;IACb,CAAC;IAED,OAAO,CAAC,OAAO;QACb,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC,gBAAgB,EAAE,CAAA;QACzB,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACjE,CAAC;IAKD,iBAAiB;QAEf,KAAK,CAAC,iBAAiB,EAAE,CAAA;QAEzB,IAAI,CAAC,WAAW,EAAE,CAAA;QAElB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAA;IAE/D,CAAC;IAGD,oBAAoB;QAElB,KAAK,CAAC,oBAAoB,EAAE,CAAA;QAE5B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAA;IAEvB,CAAC;IAGO,WAAW;QAEjB,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,EAAS,CAAA;QAC7C,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAA;QAC7C,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAA;QAC/B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAA;IAE9C,CAAC;IAED,OAAO,CAAC,KAAK;QACX,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,OAAM;QACR,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACtC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC;YAClC,KAAK,EAAE,GAAG,CAAA;;;;;;;OAOT;SACF,CAAC,CAAA;QAEF,KAAK,CAAC,QAAQ,CAAC;YACb,IAAI,EAAE,gBAAgB;YACtB,SAAS,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;SACvE,CAAC,CAAA;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,OAAO;QAC1B,MAAM,MAAM,CAAC,KAAK,CAAC;YACjB,KAAK,EAAE,GAAG,CAAA;;qCAEqB,OAAO;;OAErC;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,gBAAgB,EAAE,CAAA;IACzB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAO;QACvB,MAAM,MAAM,CAAC,KAAK,CAAC;YACjB,KAAK,EAAE,GAAG,CAAA;;;wBAGQ,OAAO;;;;;;OAMxB;SACF,CAAC,CAAA;QAEF,IAAI,CAAC,gBAAgB,EAAE,CAAA;IACzB,CAAC;;AA1H0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;+CAAsB;AACpB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;0CAAU;AACT;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;gDAAoB;AAClB;IAA5B,QAAQ,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;;6CAAkB;AACnB;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;mDAA0B;AAjBzC,YAAY;IADxB,aAAa,CAAC,eAAe,CAAC;GAClB,YAAY,CAwIxB","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { store } from '@operato/shell'\nimport { client } from '@operato/graphql'\n\nimport { UPDATE_FAVORITES } from '@things-factory/fav-base/client/index.js'\n\n@customElement('favorite-tool')\nexport class FavoriteTool extends LitElement {\n static styles = css`\n :host {\n display: inline-block;\n vertical-align: middle;\n line-height: 0;\n }\n\n [favorable] {\n opacity: 0.5;\n }\n `\n\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Object }) user: any\n @property({ type: String }) resourceId?: string\n @property({ type: Boolean }) favored?: boolean\n @property({ type: Array }) acceptedPages: any[] = []\n\n page: any\n\n render() {\n var renderable = (this.acceptedPages || []).indexOf(this.page) !== -1\n\n return renderable\n ? html`\n <md-icon @click=${this.onClick.bind(this)} ?favorable=${!this.favored}\n >${this.favored ? 'star' : 'star_border'}</md-icon\n >\n `\n : nothing\n }\n\n updated(changes) {\n if (changes.has('user')) {\n this.refreshFavorites()\n }\n\n this.favored = (this.favorites || []).includes(this.resourceId)\n }\n\n private _unsubscribe?: () => void\n\n\n connectedCallback() {\n\n super.connectedCallback()\n\n this._applyState()\n\n this._unsubscribe = store.subscribe(() => this._applyState())\n\n }\n\n\n disconnectedCallback() {\n\n super.disconnectedCallback()\n\n this._unsubscribe?.()\n\n }\n\n\n private _applyState() {\n\n const __state__ = store.getState() as any\nthis.page = __state__.route.page\n this.favorites = __state__.favorite.favorites\n this.user = __state__.auth.user\n this.resourceId = __state__.route.resourceId\n\n }\n\n onClick(event) {\n if (!this.resourceId) {\n return\n }\n\n if (this.favored) {\n this.removeFavorite(this.resourceId)\n } else {\n this.addFavorite(this.resourceId)\n }\n }\n\n async refreshFavorites() {\n if (!this.user || !this.user.email) {\n return\n }\n\n const response = await client.query({\n query: gql`\n query {\n myFavorites {\n id\n routing\n }\n }\n `\n })\n\n store.dispatch({\n type: UPDATE_FAVORITES,\n favorites: response.data.myFavorites.map(favorite => favorite.routing)\n })\n }\n\n async removeFavorite(routing) {\n await client.query({\n query: gql`\n mutation {\n deleteFavorite(routing: \"${routing}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(routing) {\n await client.query({\n query: gql`\n mutation {\n createFavorite(favorite: {\n routing: \"${routing}\"\n }) {\n id\n routing\n }\n }\n `\n })\n\n this.refreshFavorites()\n }\n}\n"]}
1
+ {"version":3,"file":"favorite-tool.js","sourceRoot":"","sources":["../../client/apptools/favorite-tool.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement, nothing } from 'lit'\nimport { customElement, property } from 'lit/decorators.js'\nimport { store } from '@operato/shell'\nimport { client } from '@operato/graphql'\n\nimport { UPDATE_FAVORITES } from '@things-factory/fav-base/client/index.js'\n\n@customElement('favorite-tool')\nexport class FavoriteTool extends LitElement {\n static styles = css`\n :host {\n display: inline-block;\n vertical-align: middle;\n line-height: 0;\n }\n\n [favorable] {\n opacity: 0.5;\n }\n `\n\n @property({ type: Array }) favorites: any[] = []\n @property({ type: Object }) user: any\n @property({ type: String }) resourceId?: string\n @property({ type: Boolean }) favored?: boolean\n @property({ type: Array }) acceptedPages: any[] = []\n\n page: any\n\n render() {\n const renderable = (this.acceptedPages || []).indexOf(this.page) !== -1\n\n return renderable\n ? html`\n <md-icon @click=${this.onClick.bind(this)} ?favorable=${!this.favored}\n >${this.favored ? 'star' : 'star_border'}</md-icon\n >\n `\n : nothing\n }\n\n updated(changes) {\n if (changes.has('user')) {\n this.refreshFavorites()\n }\n\n this.favored = (this.favorites || []).includes(this.resourceId)\n }\n\n private _unsubscribe?: () => void\n\n\n connectedCallback() {\n\n super.connectedCallback()\n\n this._applyState()\n\n this._unsubscribe = store.subscribe(() => this._applyState())\n\n }\n\n\n disconnectedCallback() {\n\n super.disconnectedCallback()\n\n this._unsubscribe?.()\n\n }\n\n\n private _applyState() {\n\n const __state__ = store.getState() as any\nthis.page = __state__.route.page\n this.favorites = __state__.favorite.favorites\n this.user = __state__.auth.user\n this.resourceId = __state__.route.resourceId\n\n }\n\n onClick(event) {\n if (!this.resourceId) {\n return\n }\n\n if (this.favored) {\n this.removeFavorite(this.resourceId)\n } else {\n this.addFavorite(this.resourceId)\n }\n }\n\n async refreshFavorites() {\n if (!this.user || !this.user.email) {\n return\n }\n\n const response = await client.query({\n query: gql`\n query {\n myFavorites {\n id\n routing\n }\n }\n `\n })\n\n store.dispatch({\n type: UPDATE_FAVORITES,\n favorites: response.data.myFavorites.map(favorite => favorite.routing)\n })\n }\n\n async removeFavorite(routing) {\n await client.mutate({\n mutation: gql`\n mutation {\n deleteFavorite(routing: \"${routing}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(routing) {\n await client.mutate({\n mutation: gql`\n mutation {\n createFavorite(favorite: {\n routing: \"${routing}\"\n }) {\n id\n routing\n }\n }\n `\n })\n\n this.refreshFavorites()\n }\n}\n"]}
@@ -10,8 +10,13 @@ export declare class BoardTileList extends LitElement {
10
10
  creatable?: boolean;
11
11
  searchText?: string;
12
12
  reorderable: boolean;
13
- private draggedItem;
13
+ updatedIds: string[];
14
+ private _draggedId;
15
+ private _dropTargetId;
16
+ private _dropSide;
14
17
  connectedCallback(): void;
18
+ private _clearDropIndicator;
19
+ private _resetDragState;
15
20
  render(): import("lit-html").TemplateResult<1>;
16
21
  updated(changes: PropertyValues<this>): void;
17
22
  onCreateBoard(e: any): void;
@@ -4,7 +4,7 @@ import '@operato/board/ox-board-creation-card.js';
4
4
  import gql from 'graphql-tag';
5
5
  import { css, html, LitElement, nothing } from 'lit';
6
6
  import { customElement, property } from 'lit/decorators.js';
7
- import { keyed } from 'lit/directives/keyed.js';
7
+ import { repeat } from 'lit/directives/repeat.js';
8
8
  import { client } from '@operato/graphql';
9
9
  import { privileged } from '@things-factory/auth-base/dist-client/index.js';
10
10
  let BoardTileList = class BoardTileList extends LitElement {
@@ -15,6 +15,10 @@ let BoardTileList = class BoardTileList extends LitElement {
15
15
  this.groups = [];
16
16
  this.creatable = false;
17
17
  this.reorderable = false;
18
+ this.updatedIds = [];
19
+ this._draggedId = null;
20
+ this._dropTargetId = null;
21
+ this._dropSide = null;
18
22
  }
19
23
  static { this.styles = [
20
24
  css `
@@ -102,6 +106,107 @@ let BoardTileList = class BoardTileList extends LitElement {
102
106
 
103
107
  [draggable='true'] {
104
108
  cursor: grab;
109
+ transition: opacity 0.2s ease, transform 0.2s ease;
110
+ }
111
+
112
+ [card].dragging {
113
+ opacity: 0.3;
114
+ transform: scale(0.95);
115
+ }
116
+
117
+ [card].drop-before {
118
+ border-left: 3px solid var(--md-sys-color-primary);
119
+ }
120
+
121
+ [card].drop-after {
122
+ border-right: 3px solid var(--md-sys-color-primary);
123
+ }
124
+
125
+ [card].flip-moving {
126
+ transition: transform 1s cubic-bezier(0.25, 0.1, 0.25, 1);
127
+ }
128
+
129
+ @keyframes drop-land {
130
+ 0% {
131
+ opacity: 0;
132
+ transform: scale(0.9);
133
+ }
134
+ 100% {
135
+ opacity: 1;
136
+ transform: scale(1);
137
+ }
138
+ }
139
+
140
+ [card].flip-dropped-hidden {
141
+ opacity: 0;
142
+ }
143
+
144
+ [card].flip-dropped {
145
+ animation: drop-land 0.5s cubic-bezier(0.22, 0.6, 0.36, 1);
146
+ }
147
+
148
+ @keyframes highlight-sweep {
149
+ 0% {
150
+ background: linear-gradient(90deg, var(--md-sys-color-primary-container) 0%, transparent 0%);
151
+ box-shadow: 0 0 8px 2px var(--md-sys-color-primary);
152
+ }
153
+ 50% {
154
+ background: linear-gradient(90deg, transparent 0%, var(--md-sys-color-primary-container) 50%, transparent 100%);
155
+ box-shadow: 0 0 12px 3px var(--md-sys-color-primary);
156
+ }
157
+ 100% {
158
+ background: transparent;
159
+ box-shadow: none;
160
+ }
161
+ }
162
+
163
+ @keyframes border-pulse {
164
+ 0%,
165
+ 100% {
166
+ outline: 2px solid transparent;
167
+ }
168
+ 25%,
169
+ 75% {
170
+ outline: 2px solid var(--md-sys-color-primary);
171
+ }
172
+ }
173
+
174
+ @keyframes subtle-bounce {
175
+ 0% {
176
+ transform: scale(1);
177
+ }
178
+ 30% {
179
+ transform: scale(1.03);
180
+ }
181
+ 100% {
182
+ transform: scale(1);
183
+ }
184
+ }
185
+
186
+ @keyframes surface-flash {
187
+ 0% {
188
+ background-color: var(--md-sys-color-primary-container);
189
+ }
190
+ 100% {
191
+ background-color: transparent;
192
+ }
193
+ }
194
+
195
+ [card].anim-sweep {
196
+ animation: highlight-sweep 1.8s ease;
197
+ border-radius: 4px;
198
+ }
199
+
200
+ [card].anim-pulse {
201
+ animation: border-pulse 1.2s ease;
202
+ }
203
+
204
+ [card].anim-bounce {
205
+ animation: subtle-bounce 0.8s ease;
206
+ }
207
+
208
+ [card].anim-flash {
209
+ animation: surface-flash 1.5s ease-out;
105
210
  }
106
211
 
107
212
  @media screen and (max-width: 800px), screen and (max-height: 600px) {
@@ -115,43 +220,167 @@ let BoardTileList = class BoardTileList extends LitElement {
115
220
  super.connectedCallback();
116
221
  if (this.reorderable) {
117
222
  this.renderRoot.addEventListener('dragstart', (e) => {
118
- const target = e.target;
119
- this.draggedItem = target.closest('[card]');
120
- e.dataTransfer?.setData('text/plain', target.innerHTML);
223
+ const target = e.target.closest('[card]');
224
+ if (!target?.id)
225
+ return;
226
+ this._draggedId = target.id;
227
+ target.classList.add('dragging');
228
+ e.dataTransfer.effectAllowed = 'move';
229
+ e.dataTransfer?.setData('text/plain', target.id);
121
230
  });
122
231
  this.renderRoot.addEventListener('dragover', (e) => {
123
232
  e.preventDefault();
124
- const target = e.target;
125
- const targetItem = target.closest('[card]');
126
- if (targetItem && targetItem !== this.draggedItem) {
127
- const targetRect = targetItem.getBoundingClientRect();
128
- const mousePos = e.clientX - targetRect.left;
129
- if (mousePos < targetRect.width / 2) {
130
- // 마우스 위치가 아이템 좌측 반절에 있을
131
- this.renderRoot.insertBefore(this.draggedItem, targetItem);
132
- }
133
- else {
134
- // 마우스 위치가 아이템 우측 반절에 있을 때
135
- this.renderRoot.insertBefore(this.draggedItem, targetItem.nextSibling);
233
+ e.dataTransfer.dropEffect = 'move';
234
+ const target = e.target.closest('[card]');
235
+ if (!target?.id || target.id === this._draggedId)
236
+ return;
237
+ const targetRect = target.getBoundingClientRect();
238
+ const mousePos = e.clientX - targetRect.left;
239
+ const side = mousePos < targetRect.width / 2 ? 'before' : 'after';
240
+ if (this._dropTargetId !== target.id || this._dropSide !== side) {
241
+ this._clearDropIndicator();
242
+ this._dropTargetId = target.id;
243
+ this._dropSide = side;
244
+ target.classList.add(side === 'before' ? 'drop-before' : 'drop-after');
245
+ }
246
+ });
247
+ this.renderRoot.addEventListener('dragleave', (e) => {
248
+ const target = e.target.closest('[card]');
249
+ if (target?.id === this._dropTargetId) {
250
+ const related = e.relatedTarget;
251
+ if (!related || !target.contains(related)) {
252
+ this._clearDropIndicator();
136
253
  }
137
254
  }
138
255
  });
139
256
  this.renderRoot.addEventListener('drop', (e) => {
140
257
  e.preventDefault();
141
- const boardIds = Array.from(this.renderRoot.querySelectorAll('[card]'))
142
- .map(board => board.getAttribute('id'))
143
- .filter(Boolean);
144
- this.dispatchEvent(new CustomEvent('reordered', {
145
- detail: {
146
- groupId: this.group,
147
- boardIds
258
+ // drop 이벤트에서 직접 타겟과 방향을 계산 (dragleave가 먼저 발생해 상태를 지울 수 있으므로)
259
+ const dropTarget = e.target.closest('[card]');
260
+ let dropTargetId = this._dropTargetId;
261
+ let dropSide = this._dropSide;
262
+ if (dropTarget?.id && dropTarget.id !== this._draggedId) {
263
+ dropTargetId = dropTarget.id;
264
+ const rect = dropTarget.getBoundingClientRect();
265
+ dropSide = e.clientX - rect.left < rect.width / 2 ? 'before' : 'after';
266
+ }
267
+ this._clearDropIndicator();
268
+ const draggedEl = this._draggedId ? this.renderRoot.querySelector(`[card][id="${this._draggedId}"]`) : null;
269
+ if (draggedEl) {
270
+ draggedEl.classList.remove('dragging');
271
+ }
272
+ if (!this._draggedId || !dropTargetId || this._draggedId === dropTargetId) {
273
+ this._resetDragState();
274
+ return;
275
+ }
276
+ // 배열 재정렬
277
+ const boards = [...this.boards];
278
+ const draggedIndex = boards.findIndex(b => b.id === this._draggedId);
279
+ if (draggedIndex === -1) {
280
+ this._resetDragState();
281
+ return;
282
+ }
283
+ const draggedBoardId = this._draggedId;
284
+ const [dragged] = boards.splice(draggedIndex, 1);
285
+ let targetIndex = boards.findIndex(b => b.id === dropTargetId);
286
+ if (dropSide === 'after')
287
+ targetIndex++;
288
+ boards.splice(targetIndex, 0, dragged);
289
+ this._resetDragState();
290
+ // FLIP 애니메이션: 이전 위치 기록
291
+ const cards = this.renderRoot.querySelectorAll('[card][id]');
292
+ const firstPositions = new Map();
293
+ cards.forEach(card => {
294
+ firstPositions.set(card.id, card.getBoundingClientRect());
295
+ });
296
+ // optimistic update → Lit 렌더
297
+ this.boards = boards;
298
+ this.updateComplete.then(() => {
299
+ const updatedCards = this.renderRoot.querySelectorAll('[card][id]');
300
+ let droppedEl = null;
301
+ updatedCards.forEach(card => {
302
+ const first = firstPositions.get(card.id);
303
+ if (!first)
304
+ return;
305
+ const last = card.getBoundingClientRect();
306
+ const dx = first.left - last.left;
307
+ const dy = first.top - last.top;
308
+ const el = card;
309
+ if (card.id === draggedBoardId) {
310
+ // 드래그한 카드: 슬라이딩 완료 후 착지하도록 일단 숨김
311
+ el.classList.add('flip-dropped-hidden');
312
+ droppedEl = el;
313
+ }
314
+ else {
315
+ // 밀려나는 카드: 이전 위치에서 새 위치로 슬라이딩
316
+ if (dx === 0 && dy === 0)
317
+ return;
318
+ // Invert: 이전 위치로 되돌림
319
+ el.style.transform = `translate(${dx}px, ${dy}px)`;
320
+ el.style.transition = 'none';
321
+ requestAnimationFrame(() => {
322
+ el.classList.add('flip-moving');
323
+ el.style.transform = '';
324
+ el.style.transition = '';
325
+ el.addEventListener('transitionend', () => {
326
+ el.classList.remove('flip-moving');
327
+ }, { once: true });
328
+ });
329
+ }
330
+ });
331
+ // 밀려나는 카드 슬라이딩 완료 후 드래그한 카드 착지 → 착지 완료 후 이벤트 발송
332
+ const boardIds = boards.map(b => b.id);
333
+ const dispatchReordered = () => {
334
+ this.dispatchEvent(new CustomEvent('reordered', {
335
+ detail: {
336
+ groupId: this.group,
337
+ boardIds
338
+ }
339
+ }));
340
+ };
341
+ if (droppedEl) {
342
+ setTimeout(() => {
343
+ ;
344
+ droppedEl.classList.remove('flip-dropped-hidden');
345
+ droppedEl.classList.add('flip-dropped');
346
+ droppedEl.addEventListener('animationend', () => {
347
+ ;
348
+ droppedEl.classList.remove('flip-dropped');
349
+ dispatchReordered();
350
+ }, { once: true });
351
+ }, 500);
352
+ }
353
+ else {
354
+ dispatchReordered();
148
355
  }
149
- }));
356
+ });
357
+ });
358
+ this.renderRoot.addEventListener('dragend', (e) => {
359
+ this._clearDropIndicator();
360
+ const target = e.target.closest('[card]');
361
+ if (target)
362
+ target.classList.remove('dragging');
363
+ this._resetDragState();
150
364
  });
151
365
  }
152
366
  }
367
+ _clearDropIndicator() {
368
+ if (this._dropTargetId) {
369
+ const el = this.renderRoot.querySelector(`[card][id="${this._dropTargetId}"]`);
370
+ if (el) {
371
+ el.classList.remove('drop-before', 'drop-after');
372
+ }
373
+ }
374
+ this._dropTargetId = null;
375
+ this._dropSide = null;
376
+ }
377
+ _resetDragState() {
378
+ this._draggedId = null;
379
+ this._dropTargetId = null;
380
+ this._dropSide = null;
381
+ }
153
382
  render() {
154
- var boards = this.boards || [];
383
+ const boards = this.boards || [];
155
384
  return html `
156
385
  ${this.creatable
157
386
  ? privileged({ privilege: 'mutation', category: 'board' }, html `
@@ -164,35 +393,48 @@ let BoardTileList = class BoardTileList extends LitElement {
164
393
  ></ox-board-creation-card>
165
394
  `)
166
395
  : nothing}
167
- ${keyed(Date.now(), boards.map(board => html `
168
- <div card draggable="true" id=${board.id}>
169
- <a href="board-viewer/${board.id}"> <img src=${board.thumbnail} /> </a>
396
+ ${repeat(boards, board => board.id, board => html `
397
+ <div card draggable="true" id=${board.id}>
398
+ <a href="board-viewer/${board.id}"> <img src=${board.thumbnail} /> </a>
170
399
 
171
- <div name>${board.name}</div>
172
- <!-- <div description>${board.description}</div> -->
400
+ <div name>${board.name}</div>
401
+ <!-- <div description>${board.description}</div> -->
173
402
 
174
- <md-icon
175
- iconBtn
176
- info
177
- @click=${e => {
403
+ <md-icon
404
+ iconBtn
405
+ info
406
+ @click=${e => {
178
407
  this.infoBoard(board);
179
408
  e.preventDefault();
180
409
  }}
181
- >info</md-icon
182
- >
410
+ >info</md-icon
411
+ >
183
412
 
184
- ${(this.favorites || []).includes(board.id)
413
+ ${(this.favorites || []).includes(board.id)
185
414
  ? html ` <md-icon iconBtn favored @click=${e => this.removeFavorite(board.id)}>star</md-icon> `
186
415
  : html ` <md-icon iconBtn @click=${e => this.addFavorite(board.id)}>star_border</md-icon> `}
187
- </div>
188
- `))}
416
+ </div>
417
+ `)}
189
418
  `;
190
419
  }
191
420
  updated(changes) {
192
- var creationCard = this.renderRoot.querySelector('ox-board-creation-card');
421
+ const creationCard = this.renderRoot.querySelector('ox-board-creation-card');
193
422
  if (creationCard) {
194
423
  creationCard.reset();
195
424
  }
425
+ if (changes.has('updatedIds') && this.updatedIds.length > 0) {
426
+ const animClasses = ['anim-sweep', 'anim-pulse', 'anim-bounce', 'anim-flash'];
427
+ for (const id of this.updatedIds) {
428
+ const card = this.renderRoot.querySelector(`[card][id="${id}"]`);
429
+ if (!card)
430
+ continue;
431
+ const animClass = animClasses[Math.floor(Math.random() * animClasses.length)];
432
+ card.classList.add(animClass);
433
+ card.addEventListener('animationend', () => {
434
+ card.classList.remove(animClass);
435
+ }, { once: true });
436
+ }
437
+ }
196
438
  }
197
439
  onCreateBoard(e) {
198
440
  this.dispatchEvent(new CustomEvent('create-board', {
@@ -205,8 +447,8 @@ let BoardTileList = class BoardTileList extends LitElement {
205
447
  }));
206
448
  }
207
449
  async removeFavorite(boardId) {
208
- await client.query({
209
- query: gql `
450
+ await client.mutate({
451
+ mutation: gql `
210
452
  mutation {
211
453
  deleteFavorite(routing: "${boardId}")
212
454
  }
@@ -215,8 +457,8 @@ let BoardTileList = class BoardTileList extends LitElement {
215
457
  this.refreshFavorites();
216
458
  }
217
459
  async addFavorite(boardId) {
218
- await client.query({
219
- query: gql `
460
+ await client.mutate({
461
+ mutation: gql `
220
462
  mutation {
221
463
  createFavorite(favorite: {
222
464
  routing: "${boardId}"
@@ -261,6 +503,10 @@ __decorate([
261
503
  property({ type: Boolean, attribute: 'reorderable' }),
262
504
  __metadata("design:type", Boolean)
263
505
  ], BoardTileList.prototype, "reorderable", void 0);
506
+ __decorate([
507
+ property({ type: Array }),
508
+ __metadata("design:type", Array)
509
+ ], BoardTileList.prototype, "updatedIds", void 0);
264
510
  BoardTileList = __decorate([
265
511
  customElement('board-tile-list')
266
512
  ], BoardTileList);
@@ -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 { keyed } from 'lit/directives/keyed.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 }\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\n private draggedItem\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\n this.draggedItem = target.closest('[card]')\n ;(e as DragEvent).dataTransfer?.setData('text/plain', target.innerHTML)\n })\n\n this.renderRoot.addEventListener('dragover', (e: Event) => {\n e.preventDefault()\n\n const target = e.target! as HTMLElement\n const targetItem = target.closest('[card]')\n if (targetItem && targetItem !== this.draggedItem) {\n const targetRect = targetItem.getBoundingClientRect()\n const mousePos = (e as DragEvent).clientX - targetRect.left\n\n if (mousePos < targetRect.width / 2) {\n // 마우스 위치가 아이템 좌측 반절에 있을 때\n this.renderRoot.insertBefore(this.draggedItem, targetItem)\n } else {\n // 마우스 위치가 아이템 우측 반절에 있을 때\n this.renderRoot.insertBefore(this.draggedItem, targetItem.nextSibling)\n }\n }\n })\n\n this.renderRoot.addEventListener('drop', (e: Event) => {\n e.preventDefault()\n\n const boardIds = Array.from(this.renderRoot.querySelectorAll('[card]'))\n .map(board => board.getAttribute('id'))\n .filter(Boolean)\n\n this.dispatchEvent(\n new CustomEvent('reordered', {\n detail: {\n groupId: this.group,\n boardIds\n }\n })\n )\n })\n }\n }\n\n render() {\n var 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 ${keyed(\n Date.now(),\n boards.map(\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\n updated(changes: PropertyValues<this>) {\n var creationCard = this.renderRoot.querySelector('ox-board-creation-card') as any\n if (creationCard) {\n creationCard.reset()\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.query({\n query: gql`\n mutation {\n deleteFavorite(routing: \"${boardId}\")\n }\n `\n })\n\n this.refreshFavorites()\n }\n\n async addFavorite(boardId) {\n await client.query({\n query: 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'\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 }\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"]}
@@ -60,7 +60,7 @@ let GroupBar = class GroupBar extends LitElement {
60
60
  }));
61
61
  }
62
62
  onWheelEvent(e) {
63
- var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
63
+ const delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail));
64
64
  this.scrollLeft -= delta * 40;
65
65
  e.preventDefault();
66
66
  }
@@ -76,12 +76,12 @@ let GroupBar = class GroupBar extends LitElement {
76
76
  this.__sb && this.__sb.updateMetrics();
77
77
  }
78
78
  if (change.has('groupId')) {
79
- var active = this.renderRoot.querySelector('li[active]');
79
+ const active = this.renderRoot.querySelector('li[active]');
80
80
  active && active.scrollIntoView();
81
81
  }
82
82
  }
83
83
  firstUpdated() {
84
- var scrollTarget = this.renderRoot.querySelector('ul');
84
+ const scrollTarget = this.renderRoot.querySelector('ul');
85
85
  /* long-press */
86
86
  longpressable(scrollTarget);
87
87
  scrollTarget.addEventListener('mousewheel', this.onWheelEvent.bind(this), false);
@@ -1 +1 @@
1
- {"version":3,"file":"group-bar.js","sourceRoot":"","sources":["../../client/board-list/group-bar.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport i18next from 'i18next'\nimport ScrollBooster from 'scrollbooster'\n\nimport { longpressable, isMobileDevice } from '@operato/utils'\nimport { privileged } from '@things-factory/auth-base/dist-client/index.js'\nimport { GroupBarStyles } from './group-bar-styles'\n@customElement('group-bar')\nexport default class GroupBar extends LitElement {\n static styles = [GroupBarStyles]\n\n @property({ type: Array }) groups?: any[]\n @property({ type: String }) groupId?: string\n @property({ type: String }) targetPage?: string\n\n @state() showAll?: boolean = false\n\n private __sb?: ScrollBooster\n\n render() {\n return html`\n <ul>\n <li ?active=${!this.groupId}>\n <a href=${this.targetPage || ''}><md-icon>dashboard</md-icon></a>\n </li>\n\n <li ?active=${this.groupId === 'favor'}>\n <a href=\"${this.targetPage}/favor\"><md-icon>star</md-icon></a>\n </li>\n\n ${privileged(\n { privilege: 'mutation', category: 'board' },\n html`<li ?active=${this.groupId === 'mywork'}>\n <a href=\"${this.targetPage}/mywork\"><md-icon>engineering</md-icon></a>\n </li>`\n )}\n ${(this.groups || []).map(\n group => html`\n <li ?active=${this.groupId === group.id} @long-press=${e => this.infoGroup(group.id)}>\n <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>\n </li>\n `\n )}\n\n <li padding></li>\n\n ${isMobileDevice()\n ? nothing\n : html`\n <li>\n <label for=\"show-all\">${i18next.t('label.show-all-board-type')}&nbsp;</label>\n <md-checkbox\n id=\"show-all\"\n ?checked=${this.showAll}\n @change=${e => this.showAllBoardType(e)}\n ></md-checkbox>\n </li>\n `}\n\n <li add>\n <md-icon @click=${e => this.infoGroup()}>add</md-icon>\n </li>\n </ul>\n `\n }\n\n infoGroup(groupId?: string) {\n this.dispatchEvent(\n new CustomEvent('info-group', {\n detail: groupId\n })\n )\n }\n\n onWheelEvent(e) {\n var delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n showAllBoardType(e) {\n this.showAll = e.target.checked\n\n this.dispatchEvent(\n new CustomEvent('show-all-board-type', {\n detail: this.showAll\n })\n )\n }\n\n updated(change) {\n if (change.has('groups')) {\n /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */\n this.__sb && this.__sb.updateMetrics()\n }\n\n if (change.has('groupId')) {\n var active = this.renderRoot.querySelector('li[active]')\n active && active.scrollIntoView()\n }\n }\n\n firstUpdated() {\n var scrollTarget = this.renderRoot.querySelector('ul')\n\n /* long-press */\n longpressable(scrollTarget!)\n\n scrollTarget!.addEventListener('mousewheel', this.onWheelEvent.bind(this), false)\n\n this.__sb = new ScrollBooster({\n viewport: this,\n content: scrollTarget,\n mode: 'x',\n onUpdate: data => {\n this.scrollLeft = data.position.x\n }\n })\n }\n}\n"]}
1
+ {"version":3,"file":"group-bar.js","sourceRoot":"","sources":["../../client/board-list/group-bar.ts"],"names":[],"mappings":";AAAA,OAAO,4BAA4B,CAAA;AAEnC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,OAAO,MAAM,SAAS,CAAA;AAC7B,OAAO,aAAa,MAAM,eAAe,CAAA;AAEzC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,gDAAgD,CAAA;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAEpC,IAAM,QAAQ,GAAd,MAAM,QAAS,SAAQ,UAAU;IAAjC;;QAOJ,YAAO,GAAa,KAAK,CAAA;IAyGpC,CAAC;aA/GQ,WAAM,GAAG,CAAC,cAAc,CAAC,AAAnB,CAAmB;IAUhC,MAAM;QACJ,OAAO,IAAI,CAAA;;sBAEO,CAAC,IAAI,CAAC,OAAO;oBACf,IAAI,CAAC,UAAU,IAAI,EAAE;;;sBAGnB,IAAI,CAAC,OAAO,KAAK,OAAO;qBACzB,IAAI,CAAC,UAAU;;;UAG1B,UAAU,CACV,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,EAC5C,IAAI,CAAA,eAAe,IAAI,CAAC,OAAO,KAAK,QAAQ;uBAC/B,IAAI,CAAC,UAAU;gBACtB,CACP;UACC,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,GAAG,CACvB,KAAK,CAAC,EAAE,CAAC,IAAI,CAAA;0BACG,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;wBACxE,GAAG,IAAI,CAAC,UAAU,IAAI,KAAK,CAAC,EAAE,EAAE,IAAI,KAAK,CAAC,IAAI;;WAE3D,CACF;;;;UAIC,cAAc,EAAE;YAChB,CAAC,CAAC,OAAO;YACT,CAAC,CAAC,IAAI,CAAA;;wCAEwB,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAC;;;6BAGjD,IAAI,CAAC,OAAO;4BACb,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;;;aAG5C;;;4BAGe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE;;;KAG5C,CAAA;IACH,CAAC;IAED,SAAS,CAAC,OAAgB;QACxB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,YAAY,EAAE;YAC5B,MAAM,EAAE,OAAO;SAChB,CAAC,CACH,CAAA;IACH,CAAC;IAED,YAAY,CAAC,CAAC;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;QAClE,IAAI,CAAC,UAAU,IAAI,KAAK,GAAG,EAAE,CAAA;QAE7B,CAAC,CAAC,cAAc,EAAE,CAAA;IACpB,CAAC;IAED,gBAAgB,CAAC,CAAC;QAChB,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAA;QAE/B,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAC,qBAAqB,EAAE;YACrC,MAAM,EAAE,IAAI,CAAC,OAAO;SACrB,CAAC,CACH,CAAA;IACH,CAAC;IAED,OAAO,CAAC,MAAM;QACZ,IAAI,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,sDAAsD;YACtD,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAA;QACxC,CAAC;QAED,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,YAAY,CAAC,CAAA;YAC1D,MAAM,IAAI,MAAM,CAAC,cAAc,EAAE,CAAA;QACnC,CAAC;IACH,CAAC;IAED,YAAY;QACV,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;QAExD,gBAAgB;QAChB,aAAa,CAAC,YAAa,CAAC,CAAA;QAE5B,YAAa,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,CAAC,CAAA;QAEjF,IAAI,CAAC,IAAI,GAAG,IAAI,aAAa,CAAC;YAC5B,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,YAAY;YACrB,IAAI,EAAE,GAAG;YACT,QAAQ,EAAE,IAAI,CAAC,EAAE;gBACf,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAA;YACnC,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;;AA5G0B;IAA1B,QAAQ,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;;wCAAe;AACb;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;yCAAiB;AAChB;IAA3B,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;;4CAAoB;AAEtC;IAAR,KAAK,EAAE;;yCAA0B;AAPf,QAAQ;IAD5B,aAAa,CAAC,WAAW,CAAC;GACN,QAAQ,CAgH5B;eAhHoB,QAAQ","sourcesContent":["import '@material/web/icon/icon.js'\n\nimport { html, LitElement, nothing } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\nimport i18next from 'i18next'\nimport ScrollBooster from 'scrollbooster'\n\nimport { longpressable, isMobileDevice } from '@operato/utils'\nimport { privileged } from '@things-factory/auth-base/dist-client/index.js'\nimport { GroupBarStyles } from './group-bar-styles'\n@customElement('group-bar')\nexport default class GroupBar extends LitElement {\n static styles = [GroupBarStyles]\n\n @property({ type: Array }) groups?: any[]\n @property({ type: String }) groupId?: string\n @property({ type: String }) targetPage?: string\n\n @state() showAll?: boolean = false\n\n private __sb?: ScrollBooster\n\n render() {\n return html`\n <ul>\n <li ?active=${!this.groupId}>\n <a href=${this.targetPage || ''}><md-icon>dashboard</md-icon></a>\n </li>\n\n <li ?active=${this.groupId === 'favor'}>\n <a href=\"${this.targetPage}/favor\"><md-icon>star</md-icon></a>\n </li>\n\n ${privileged(\n { privilege: 'mutation', category: 'board' },\n html`<li ?active=${this.groupId === 'mywork'}>\n <a href=\"${this.targetPage}/mywork\"><md-icon>engineering</md-icon></a>\n </li>`\n )}\n ${(this.groups || []).map(\n group => html`\n <li ?active=${this.groupId === group.id} @long-press=${e => this.infoGroup(group.id)}>\n <a href=${`${this.targetPage}/${group.id}`}>${group.name}</a>\n </li>\n `\n )}\n\n <li padding></li>\n\n ${isMobileDevice()\n ? nothing\n : html`\n <li>\n <label for=\"show-all\">${i18next.t('label.show-all-board-type')}&nbsp;</label>\n <md-checkbox\n id=\"show-all\"\n ?checked=${this.showAll}\n @change=${e => this.showAllBoardType(e)}\n ></md-checkbox>\n </li>\n `}\n\n <li add>\n <md-icon @click=${e => this.infoGroup()}>add</md-icon>\n </li>\n </ul>\n `\n }\n\n infoGroup(groupId?: string) {\n this.dispatchEvent(\n new CustomEvent('info-group', {\n detail: groupId\n })\n )\n }\n\n onWheelEvent(e) {\n const delta = Math.max(-1, Math.min(1, e.wheelDelta || -e.detail))\n this.scrollLeft -= delta * 40\n\n e.preventDefault()\n }\n\n showAllBoardType(e) {\n this.showAll = e.target.checked\n\n this.dispatchEvent(\n new CustomEvent('show-all-board-type', {\n detail: this.showAll\n })\n )\n }\n\n updated(change) {\n if (change.has('groups')) {\n /* groups가 바뀔 때마다, contents의 폭이 달라지므로, 다시 폭을 계산해준다. */\n this.__sb && this.__sb.updateMetrics()\n }\n\n if (change.has('groupId')) {\n const active = this.renderRoot.querySelector('li[active]')\n active && active.scrollIntoView()\n }\n }\n\n firstUpdated() {\n const scrollTarget = this.renderRoot.querySelector('ul')\n\n /* long-press */\n longpressable(scrollTarget!)\n\n scrollTarget!.addEventListener('mousewheel', this.onWheelEvent.bind(this), false)\n\n this.__sb = new ScrollBooster({\n viewport: this,\n content: scrollTarget,\n mode: 'x',\n onUpdate: data => {\n this.scrollLeft = data.position.x\n }\n })\n }\n}\n"]}