@things-factory/operato-board 6.1.112 → 6.1.113

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.
@@ -8,9 +8,11 @@ export declare class BoardInfo extends LitElement {
8
8
  board: any;
9
9
  boardGroupList: any[];
10
10
  playGroupList: any[];
11
+ private originalName?;
11
12
  render(): import("lit-html").TemplateResult<1>;
12
13
  firstUpdated(): void;
13
14
  refresh(): Promise<void>;
15
+ cloneBoard(): Promise<void>;
14
16
  updateBoard(): Promise<void>;
15
17
  deleteBoard(): Promise<void>;
16
18
  joinPlayGroup(group: any): Promise<void>;
@@ -34,7 +34,10 @@ let BoardInfo = class BoardInfo extends LitElement {
34
34
  <input
35
35
  type="text"
36
36
  .value=${board.name}
37
- @change=${e => (this.board.name = e.target.value)}
37
+ @change=${e => {
38
+ this.board.name = e.target.value;
39
+ this.requestUpdate();
40
+ }}
38
41
  ?disabled=${!this.enableModeller}
39
42
  />
40
43
 
@@ -77,6 +80,14 @@ let BoardInfo = class BoardInfo extends LitElement {
77
80
  @click=${this.deleteBoard.bind(this)}
78
81
  icon="delete_outline"
79
82
  ></mwc-button>
83
+ <mwc-button
84
+ dense
85
+ raised
86
+ label=${String(i18next.t('button.copy'))}
87
+ ?disabled=${!this.enableModeller || !this.originalName || this.originalName == this.board.name}
88
+ @click=${this.cloneBoard.bind(this)}
89
+ icon="content_copy"
90
+ ></mwc-button>
80
91
  <mwc-button
81
92
  dense
82
93
  raised
@@ -170,8 +181,24 @@ let BoardInfo = class BoardInfo extends LitElement {
170
181
  this.board = response.board;
171
182
  this.boardGroupList = response.groups.items;
172
183
  this.playGroupList = response.playGroups.items;
184
+ this.originalName = this.board.name;
173
185
  this.groupId = (_a = this.board.group) === null || _a === void 0 ? void 0 : _a.id;
174
186
  }
187
+ async cloneBoard() {
188
+ if (!this.originalName || this.board.name == this.originalName) {
189
+ document.dispatchEvent(new CustomEvent('notify', {
190
+ detail: {
191
+ level: 'error',
192
+ message: i18next.t('error.name must be unique from the original board', { name: this.originalName })
193
+ }
194
+ }));
195
+ return;
196
+ }
197
+ this.dispatchEvent(new CustomEvent('clone-board', {
198
+ detail: this.board
199
+ }));
200
+ this.close();
201
+ }
175
202
  async updateBoard() {
176
203
  this.dispatchEvent(new CustomEvent('update-board', {
177
204
  detail: this.board
@@ -179,6 +206,7 @@ let BoardInfo = class BoardInfo extends LitElement {
179
206
  this.close();
180
207
  }
181
208
  async deleteBoard() {
209
+ // TODO 삭제하려는 보드이름을 입력하게 해서, 한번 더 확인할 것.
182
210
  this.dispatchEvent(new CustomEvent('delete-board', {
183
211
  detail: this.board
184
212
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"board-info.js","sourceRoot":"","sources":["../../client/viewparts/board-info.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-icon'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\nimport { client } from '@operato/graphql'\nimport { navigate } from '@operato/shell'\n\n@customElement('board-info')\nexport class BoardInfo extends LitElement {\n static styles = [\n css`\n :host {\n display: block;\n background-color: var(--main-section-background-color);\n height: 100%;\n min-width: 350px;\n overflow: auto;\n position: relative;\n\n --form-grid-gap: 2px 0;\n --input-field-padding: var(--padding-default);\n --legend-padding: var(--padding-default) 0 var(--padding-narrow) 0;\n --mdc-button-horizontal-padding: var(--padding-default);\n }\n\n img {\n display: block;\n\n margin: auto;\n max-width: 100%;\n max-height: 100%;\n border-bottom: 2px solid rgba(0, 0, 0, 0.1);\n }\n\n form {\n display: grid;\n grid-template-columns: repeat(12, 1fr);\n grid-gap: var(--form-grid-gap);\n grid-auto-rows: minmax(24px, auto);\n padding: var(--padding-wide);\n align-items: center;\n }\n\n [buttons] {\n grid-column: span 12;\n padding: var(--padding-default) 0;\n text-align: right;\n }\n\n [buttons] * {\n margin: 0 0 0 var(--margin-narrow);\n }\n [danger] {\n float: left;\n margin: 0 var(--margin-narrow) 0 0;\n --mdc-theme-primary: var(--status-danger-color);\n }\n\n fieldset {\n display: contents;\n }\n\n legend {\n grid-column: span 12;\n padding: var(--legend-padding);\n font: var(--legend-font);\n color: var(--legend-text-color);\n text-transform: capitalize;\n }\n\n label {\n grid-column: span 12;\n text-transform: capitalize;\n color: var(--label-color);\n font: var(--label-font);\n }\n\n span {\n grid-column: span 12;\n border-bottom: var(--border-dark-color);\n margin-bottom: var(--margin-default);\n padding-bottom: var(--padding-narrow);\n font: var(--input-field-font);\n }\n span mwc-icon {\n vertical-align: middle;\n font-size: var(--fontsize-large);\n color: var(--primary-color);\n }\n\n input,\n table,\n select,\n textarea,\n [custom-input] {\n grid-column: span 12;\n\n border: var(--input-field-border);\n border-radius: var(--input-field-border-radius);\n margin-bottom: var(--margin-default);\n padding: var(--input-field-padding);\n font: var(--input-field-font);\n }\n\n input[type='checkbox'],\n input[type='radio'] {\n place-self: center;\n margin: 0;\n grid-column: 1;\n }\n\n input[type='checkbox'] + label,\n input[type='radio'] + label {\n text-align: left;\n grid-column: span 11 / auto;\n\n font: var(--form-sublabel-font);\n color: var(--form-sublabel-color);\n }\n\n input:focus {\n outline: none;\n border: 1px solid var(--focus-background-color);\n }\n\n @media screen and (max-width: 460px) {\n :host {\n width: 100vw;\n }\n }\n `\n ]\n\n @property({ type: String }) boardId?: string\n @property({ type: String }) groupId?: string\n @property({ type: Boolean, attribute: 'enable-modeller' }) enableModeller?: boolean\n\n @state() board: any\n @state() boardGroupList: any[] = []\n @state() playGroupList: any[] = []\n\n render() {\n var board = this.board || { name: '', description: '', playGroups: [] }\n var boardGroupList = this.boardGroupList || []\n var playGroupList = (this.playGroupList || []).map(group => {\n return {\n ...group,\n checked: false\n }\n })\n ;(board.playGroups || []).map(group => {\n var playGroup = playGroupList.find(g => g.id == group.id)\n if (playGroup) {\n playGroup.checked = true\n }\n })\n\n return html`\n ${board.thumbnail ? html` <img src=${board.thumbnail} /> ` : html``}\n\n <form>\n <fieldset>\n <legend>${i18next.t('label.information')}</legend>\n <label>${i18next.t('label.name')}</label>\n <input\n type=\"text\"\n .value=${board.name}\n @change=${e => (this.board.name = e.target.value)}\n ?disabled=${!this.enableModeller}\n />\n\n <label>${i18next.t('label.description')}</label>\n <input\n type=\"text\"\n .value=${board.description}\n @change=${e => (this.board.description = e.target.value)}\n ?disabled=${!this.enableModeller}\n />\n\n <label>${i18next.t('label.group')}</label>\n <select\n @change=${e => (this.board.groupId = e.target.value)}\n .value=${this.groupId || ''}\n ?disabled=${!this.enableModeller}\n >\n <option value=\"\" ?selected=${'' == this.groupId}></option>\n ${boardGroupList.map(\n item => html` <option .value=${item.id} ?selected=${item.id == this.groupId}>${item.name}</option> `\n )}\n </select>\n <label>${i18next.t('label.creator')}</label>\n <span>\n <mwc-icon>person</mwc-icon> ${(board.creator && board.creator.name) || 'anonymous'}\n <mwc-icon>schedule</mwc-icon> ${new Date(Number(board.createdAt)).toLocaleString()}\n </span>\n\n <label>${i18next.t('label.updater')}</label>\n <span>\n <mwc-icon>person</mwc-icon> ${(board.updater && board.updater.name) || 'anonymouse'}\n <mwc-icon>schedule</mwc-icon> ${new Date(Number(board.updatedAt)).toLocaleString()}\n </span>\n\n <div buttons>\n <mwc-button\n dense\n raised\n danger\n label=${String(i18next.t('button.delete'))}\n ?disabled=${!this.enableModeller}\n @click=${this.deleteBoard.bind(this)}\n icon=\"delete_outline\"\n ></mwc-button>\n <mwc-button\n dense\n raised\n label=${String(i18next.t('button.save'))}\n ?disabled=${!this.enableModeller}\n @click=${this.updateBoard.bind(this)}\n icon=\"done\"\n ></mwc-button>\n <mwc-button\n dense\n raised\n label=\"edit\"\n ?disabled=${!this.enableModeller}\n @click=${() => navigate(`${'board-modeller/' + this.boardId}`)}\n icon=\"drive_file_rename_outline\"\n ></mwc-button>\n </div>\n </fieldset>\n\n <fieldset>\n <legend>${i18next.t('label.play-group')}</legend>\n\n ${playGroupList.map(\n item => html`\n <input\n type=\"checkbox\"\n value=${item.id}\n .checked=${item.checked}\n @change=${e => {\n e.target.checked ? this.joinPlayGroup(item) : this.leavePlayGroup(item)\n }}\n />\n <label>${item.name}</label>\n `\n )}\n </fieldset>\n </form>\n `\n }\n\n firstUpdated() {\n this.refresh()\n }\n\n async refresh() {\n var response = (\n await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n id\n name\n description\n group {\n id\n name\n }\n playGroups {\n id\n name\n }\n thumbnail\n createdAt\n creator {\n id\n name\n }\n updatedAt\n updater {\n id\n name\n }\n }\n\n groups {\n items {\n id\n name\n description\n }\n }\n\n playGroups {\n items {\n id\n name\n description\n }\n total\n }\n }\n `,\n variables: { id: this.boardId }\n })\n ).data\n\n this.board = response.board\n this.boardGroupList = response.groups.items\n this.playGroupList = response.playGroups.items\n\n this.groupId = this.board.group?.id\n }\n\n async updateBoard() {\n this.dispatchEvent(\n new CustomEvent('update-board', {\n detail: this.board\n })\n )\n\n this.close()\n }\n\n async deleteBoard() {\n this.dispatchEvent(\n new CustomEvent('delete-board', {\n detail: this.board\n })\n )\n\n this.close()\n }\n\n async joinPlayGroup(group) {\n this.dispatchEvent(\n new CustomEvent('join-playgroup', {\n detail: {\n board: this.board,\n playGroup: group\n }\n })\n )\n }\n\n async leavePlayGroup(group) {\n this.dispatchEvent(\n new CustomEvent('leave-playgroup', {\n detail: {\n board: this.board,\n playGroup: group\n }\n })\n )\n }\n\n close() {\n history.back()\n }\n}\n"]}
1
+ {"version":3,"file":"board-info.js","sourceRoot":"","sources":["../../client/viewparts/board-info.ts"],"names":[],"mappings":"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","sourcesContent":["import '@material/mwc-icon'\n\nimport gql from 'graphql-tag'\nimport { css, html, LitElement } from 'lit'\nimport { customElement, property, state } from 'lit/decorators.js'\n\nimport { i18next } from '@operato/i18n'\nimport { client } from '@operato/graphql'\nimport { navigate } from '@operato/shell'\n\n@customElement('board-info')\nexport class BoardInfo extends LitElement {\n static styles = [\n css`\n :host {\n display: block;\n background-color: var(--main-section-background-color);\n height: 100%;\n min-width: 350px;\n overflow: auto;\n position: relative;\n\n --form-grid-gap: 2px 0;\n --input-field-padding: var(--padding-default);\n --legend-padding: var(--padding-default) 0 var(--padding-narrow) 0;\n --mdc-button-horizontal-padding: var(--padding-default);\n }\n\n img {\n display: block;\n\n margin: auto;\n max-width: 100%;\n max-height: 100%;\n border-bottom: 2px solid rgba(0, 0, 0, 0.1);\n }\n\n form {\n display: grid;\n grid-template-columns: repeat(12, 1fr);\n grid-gap: var(--form-grid-gap);\n grid-auto-rows: minmax(24px, auto);\n padding: var(--padding-wide);\n align-items: center;\n }\n\n [buttons] {\n grid-column: span 12;\n padding: var(--padding-default) 0;\n text-align: right;\n }\n\n [buttons] * {\n margin: 0 0 0 var(--margin-narrow);\n }\n [danger] {\n float: left;\n margin: 0 var(--margin-narrow) 0 0;\n --mdc-theme-primary: var(--status-danger-color);\n }\n\n fieldset {\n display: contents;\n }\n\n legend {\n grid-column: span 12;\n padding: var(--legend-padding);\n font: var(--legend-font);\n color: var(--legend-text-color);\n text-transform: capitalize;\n }\n\n label {\n grid-column: span 12;\n text-transform: capitalize;\n color: var(--label-color);\n font: var(--label-font);\n }\n\n span {\n grid-column: span 12;\n border-bottom: var(--border-dark-color);\n margin-bottom: var(--margin-default);\n padding-bottom: var(--padding-narrow);\n font: var(--input-field-font);\n }\n span mwc-icon {\n vertical-align: middle;\n font-size: var(--fontsize-large);\n color: var(--primary-color);\n }\n\n input,\n table,\n select,\n textarea,\n [custom-input] {\n grid-column: span 12;\n\n border: var(--input-field-border);\n border-radius: var(--input-field-border-radius);\n margin-bottom: var(--margin-default);\n padding: var(--input-field-padding);\n font: var(--input-field-font);\n }\n\n input[type='checkbox'],\n input[type='radio'] {\n place-self: center;\n margin: 0;\n grid-column: 1;\n }\n\n input[type='checkbox'] + label,\n input[type='radio'] + label {\n text-align: left;\n grid-column: span 11 / auto;\n\n font: var(--form-sublabel-font);\n color: var(--form-sublabel-color);\n }\n\n input:focus {\n outline: none;\n border: 1px solid var(--focus-background-color);\n }\n\n @media screen and (max-width: 460px) {\n :host {\n width: 100vw;\n }\n }\n `\n ]\n\n @property({ type: String }) boardId?: string\n @property({ type: String }) groupId?: string\n @property({ type: Boolean, attribute: 'enable-modeller' }) enableModeller?: boolean\n\n @state() board: any\n @state() boardGroupList: any[] = []\n @state() playGroupList: any[] = []\n\n private originalName?: string\n\n render() {\n var board = this.board || { name: '', description: '', playGroups: [] }\n var boardGroupList = this.boardGroupList || []\n var playGroupList = (this.playGroupList || []).map(group => {\n return {\n ...group,\n checked: false\n }\n })\n ;(board.playGroups || []).map(group => {\n var playGroup = playGroupList.find(g => g.id == group.id)\n if (playGroup) {\n playGroup.checked = true\n }\n })\n\n return html`\n ${board.thumbnail ? html` <img src=${board.thumbnail} /> ` : html``}\n\n <form>\n <fieldset>\n <legend>${i18next.t('label.information')}</legend>\n <label>${i18next.t('label.name')}</label>\n <input\n type=\"text\"\n .value=${board.name}\n @change=${e => {\n this.board.name = e.target.value\n this.requestUpdate()\n }}\n ?disabled=${!this.enableModeller}\n />\n\n <label>${i18next.t('label.description')}</label>\n <input\n type=\"text\"\n .value=${board.description}\n @change=${e => (this.board.description = e.target.value)}\n ?disabled=${!this.enableModeller}\n />\n\n <label>${i18next.t('label.group')}</label>\n <select\n @change=${e => (this.board.groupId = e.target.value)}\n .value=${this.groupId || ''}\n ?disabled=${!this.enableModeller}\n >\n <option value=\"\" ?selected=${'' == this.groupId}></option>\n ${boardGroupList.map(\n item => html` <option .value=${item.id} ?selected=${item.id == this.groupId}>${item.name}</option> `\n )}\n </select>\n <label>${i18next.t('label.creator')}</label>\n <span>\n <mwc-icon>person</mwc-icon> ${(board.creator && board.creator.name) || 'anonymous'}\n <mwc-icon>schedule</mwc-icon> ${new Date(Number(board.createdAt)).toLocaleString()}\n </span>\n\n <label>${i18next.t('label.updater')}</label>\n <span>\n <mwc-icon>person</mwc-icon> ${(board.updater && board.updater.name) || 'anonymouse'}\n <mwc-icon>schedule</mwc-icon> ${new Date(Number(board.updatedAt)).toLocaleString()}\n </span>\n\n <div buttons>\n <mwc-button\n dense\n raised\n danger\n label=${String(i18next.t('button.delete'))}\n ?disabled=${!this.enableModeller}\n @click=${this.deleteBoard.bind(this)}\n icon=\"delete_outline\"\n ></mwc-button>\n <mwc-button\n dense\n raised\n label=${String(i18next.t('button.copy'))}\n ?disabled=${!this.enableModeller || !this.originalName || this.originalName == this.board.name}\n @click=${this.cloneBoard.bind(this)}\n icon=\"content_copy\"\n ></mwc-button>\n <mwc-button\n dense\n raised\n label=${String(i18next.t('button.save'))}\n ?disabled=${!this.enableModeller}\n @click=${this.updateBoard.bind(this)}\n icon=\"done\"\n ></mwc-button>\n <mwc-button\n dense\n raised\n label=\"edit\"\n ?disabled=${!this.enableModeller}\n @click=${() => navigate(`${'board-modeller/' + this.boardId}`)}\n icon=\"drive_file_rename_outline\"\n ></mwc-button>\n </div>\n </fieldset>\n\n <fieldset>\n <legend>${i18next.t('label.play-group')}</legend>\n\n ${playGroupList.map(\n item => html`\n <input\n type=\"checkbox\"\n value=${item.id}\n .checked=${item.checked}\n @change=${e => {\n e.target.checked ? this.joinPlayGroup(item) : this.leavePlayGroup(item)\n }}\n />\n <label>${item.name}</label>\n `\n )}\n </fieldset>\n </form>\n `\n }\n\n firstUpdated() {\n this.refresh()\n }\n\n async refresh() {\n var response = (\n await client.query({\n query: gql`\n query FetchBoardById($id: String!) {\n board(id: $id) {\n id\n name\n description\n group {\n id\n name\n }\n playGroups {\n id\n name\n }\n thumbnail\n createdAt\n creator {\n id\n name\n }\n updatedAt\n updater {\n id\n name\n }\n }\n\n groups {\n items {\n id\n name\n description\n }\n }\n\n playGroups {\n items {\n id\n name\n description\n }\n total\n }\n }\n `,\n variables: { id: this.boardId }\n })\n ).data\n\n this.board = response.board\n this.boardGroupList = response.groups.items\n this.playGroupList = response.playGroups.items\n this.originalName = this.board.name\n\n this.groupId = this.board.group?.id\n }\n\n async cloneBoard() {\n if (!this.originalName || this.board.name == this.originalName) {\n document.dispatchEvent(\n new CustomEvent('notify', {\n detail: {\n level: 'error',\n message: i18next.t('error.name must be unique from the original board', { name: this.originalName })\n }\n })\n )\n\n return\n }\n\n this.dispatchEvent(\n new CustomEvent('clone-board', {\n detail: this.board\n })\n )\n\n this.close()\n }\n\n async updateBoard() {\n this.dispatchEvent(\n new CustomEvent('update-board', {\n detail: this.board\n })\n )\n\n this.close()\n }\n\n async deleteBoard() {\n // TODO 삭제하려는 보드이름을 입력하게 해서, 한번 더 확인할 것.\n this.dispatchEvent(\n new CustomEvent('delete-board', {\n detail: this.board\n })\n )\n\n this.close()\n }\n\n async joinPlayGroup(group) {\n this.dispatchEvent(\n new CustomEvent('join-playgroup', {\n detail: {\n board: this.board,\n playGroup: group\n }\n })\n )\n }\n\n async leavePlayGroup(group) {\n this.dispatchEvent(\n new CustomEvent('leave-playgroup', {\n detail: {\n board: this.board,\n playGroup: group\n }\n })\n )\n }\n\n close() {\n history.back()\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@things-factory/operato-board",
3
- "version": "6.1.112",
3
+ "version": "6.1.113",
4
4
  "main": "dist-server/index.js",
5
5
  "browser": "dist-client/index.js",
6
6
  "things-factory": true,
@@ -85,7 +85,7 @@
85
85
  "@operato/utils": "^1.0.1",
86
86
  "@things-factory/apptool-ui": "^6.1.112",
87
87
  "@things-factory/auth-ui": "^6.1.112",
88
- "@things-factory/board-service": "^6.1.112",
88
+ "@things-factory/board-service": "^6.1.113",
89
89
  "@things-factory/board-ui": "^6.1.112",
90
90
  "@things-factory/context-ui": "^6.1.112",
91
91
  "@things-factory/export-ui": "^6.1.112",
@@ -116,8 +116,8 @@
116
116
  "@things-factory/system-ui": "^6.1.112"
117
117
  },
118
118
  "devDependencies": {
119
- "@things-factory/board-test": "^6.1.112",
119
+ "@things-factory/board-test": "^6.1.113",
120
120
  "@things-factory/builder": "^6.1.112"
121
121
  },
122
- "gitHead": "d33ec2c83a2dafeedd6a32921574b726f6fca785"
122
+ "gitHead": "5c2a899ed475188d9555fcdd70db9d41b298a2ed"
123
123
  }
package/schema.gql CHANGED
@@ -1413,6 +1413,9 @@ type Mutation {
1413
1413
  attachContact(contactId: String!, id: String!): Employee!
1414
1414
  cancelInvitation(email: String!, reference: String!, type: String!): Boolean!
1415
1415
 
1416
+ """To clone a Board from existing Board"""
1417
+ cloneBoard(id: String!, patch: BoardPatch!): Board!
1418
+
1416
1419
  """To connect a connection"""
1417
1420
  connectConnection(name: String!): Connection!
1418
1421
 
@@ -15,6 +15,7 @@
15
15
  "error.license expiration notice": "License Expiration Notice",
16
16
  "error.your license due date is x, please renewal your license!": "Your license due date is {x}, please renewal your license!",
17
17
  "menu.board-template": "board template",
18
+ "text.board cloned": "board '{board}' is cloned successfully",
18
19
  "text.board created": "board '{board}' is created successfully",
19
20
  "text.board updated": "board '{board}' is updated successfully",
20
21
  "text.board deleted": "board '{board}' is deleted successfully",
@@ -15,6 +15,7 @@
15
15
  "error.license expiration notice": "ライセンス満了予定のお知らせ",
16
16
  "error.your license due date is x, please renewal your license!": "ライセンス期限は{x}です. ライセンスを更新してください!",
17
17
  "menu.board-template": "ボードテンプレート管理",
18
+ "text.board cloned": "ボード '{board}' は正常にクローンされました",
18
19
  "text.board created": "ボード'{board}'が作成されました",
19
20
  "text.board updated": "ボード'{board}'が修正されました",
20
21
  "text.board deleted": "ボード'{board}'が削除されました",
@@ -15,6 +15,7 @@
15
15
  "error.license expiration notice": "라이선스 만료예정 알림",
16
16
  "error.your license due date is x, please renewal your license!": "라이센스 기한은 {x}입니다. 라이센스를 갱신하십시오!",
17
17
  "menu.board-template": "보드 템플릿 관리",
18
+ "text.board cloned": "보드 '{board}'이 복사되었습니다",
18
19
  "text.board created": "보드 '{board}'이 생성되었습니다",
19
20
  "text.board updated": "보드 '{board}'이 수정되었습니다",
20
21
  "text.board deleted": "보드 '{board}'이 삭제되었습니다",
@@ -15,6 +15,7 @@
15
15
  "error.license expiration notice": "Notis Tamat Tempoh Lesen",
16
16
  "error.your license due date is x, please renewal your license!": "Tarikh tamat tempoh lesen anda adalah {x}, sila perbaharui lesen anda!",
17
17
  "menu.board-template": "templat papan",
18
+ "text.board cloned": "papan '{board}' telah berjaya dikelonkan",
18
19
  "text.board created": "papan '{board}' berjaya dicipta",
19
20
  "text.board updated": "papan '{board}' berjaya dikemaskini",
20
21
  "text.board deleted": "papan '{board}' berjaya dipadam",
@@ -15,6 +15,7 @@
15
15
  "error.license expiration notice": "许可证到期提醒",
16
16
  "error.your license due date is x, please renewal your license!": "您的许可证到期日期为{x},请续订您的许可证!",
17
17
  "menu.board-template": "看板模板",
18
+ "text.board cloned": "看板 '{board}' 已成功克隆",
18
19
  "text.board created": "看板 '{board}' 创建成功",
19
20
  "text.board updated": "看板 '{board}' 更新成功",
20
21
  "text.board deleted": "看板 '{board}' 删除成功",