Skip to content

Commit 194b874

Browse files
committed
Updated matrix & fb-runner image
1 parent a40c6a5 commit 194b874

File tree

4 files changed

+147
-60
lines changed

4 files changed

+147
-60
lines changed

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ruby '3.1.3'
1010
# branch: 'accessibility-statement'
1111
# gem 'metadata_presenter', path: '../fb-metadata-presenter'
1212
# gem 'metadata_presenter', '3.3.5'
13-
gem 'metadata_presenter', git: 'https://github.com/cabinetoffice/fb-metadata-presenter.git', ref: '5f0a611'
13+
gem 'metadata_presenter', git: 'https://github.com/cabinetoffice/fb-metadata-presenter.git', ref: '236da64'
1414

1515
gem 'activerecord-session_store'
1616
gem 'administrate'

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
GIT
22
remote: https://github.com/cabinetoffice/fb-metadata-presenter.git
3-
revision: 5f0a611748be4729683cc610e6c2605dd5d5285e
4-
ref: 5f0a611
3+
revision: 236da6454e168129c6a97f14f3f59695f55015f3
4+
ref: 236da64
55
specs:
66
metadata_presenter (3.4.4)
77
govspeak (~> 7.1)

app/javascript/src/question_matrix.js

Lines changed: 143 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Matrix component extension of Question.
66
*
77
* Supports editable legend/hint, row labels, column labels,
8-
* mode switching confirmation, and row/column insertion in the editor.
8+
* mode switching confirmation, and row/column insertion/removal in the editor.
99
**/
1010

1111
const utilities = require('./utilities');
@@ -24,7 +24,8 @@ const SELECTOR_HEADER_ROW = "[data-fb-matrix-header-row]";
2424
const SELECTOR_BODY = "[data-fb-matrix-body]";
2525
const SELECTOR_ADD_ROW = "[data-fb-matrix-add-row]";
2626
const SELECTOR_ADD_COLUMN = "[data-fb-matrix-add-column]";
27-
27+
const SELECTOR_REMOVE_ROW = "[data-fb-matrix-remove-row]";
28+
const SELECTOR_REMOVE_COLUMN = "[data-fb-matrix-remove-column]";
2829

2930
class MatrixQuestion extends Question {
3031
constructor($node, config) {
@@ -35,12 +36,16 @@ class MatrixQuestion extends Question {
3536

3637
$node.addClass("MatrixQuestion");
3738

38-
this._rowCount = Array.isArray(this.data.rows) ? this.data.rows.length : 0;
39-
this._columnCount = Array.isArray(this.data.columns) ? this.data.columns.length : 0;
40-
39+
this.initialiseEditableState();
4140
this.initialiseMatrixLabelEditing(config);
4241
this.initialiseModeSwitchConfirmation(config);
4342
this.initialiseAxisControls(config);
43+
this.initialiseDeleteControls();
44+
}
45+
46+
initialiseEditableState() {
47+
this.$node.find(SELECTOR_MODE).prop("disabled", false);
48+
this.$node.find(SELECTOR_MODE).data("fb-matrix-mode-original", this.data.mode);
4449
}
4550

4651
initialiseMatrixLabelEditing(config) {
@@ -59,25 +64,41 @@ class MatrixQuestion extends Question {
5964
});
6065
}
6166

62-
bindRowLabel($node, config) {
67+
bindRowHeading($node, config) {
6368
const editable = createEditableLabel($node, config);
64-
$node.off("blur.matrix-row-label").on("blur.matrix-row-label", () => {
65-
questionSyncRowLabel(this, editable.content, $node.data("fb-matrix-row-id"));
69+
$node.off("blur.matrix-row-heading").on("blur.matrix-row-heading", () => {
70+
this.data.row_heading = editable.content;
71+
this.editable.emitSaveRequired();
6672
});
6773
}
6874

69-
bindRowHeading($node, config) {
75+
bindRowLabel($node, config) {
7076
const editable = createEditableLabel($node, config);
71-
$node.off("blur.matrix-row-heading").on("blur.matrix-row-heading", () => {
72-
this.data.row_heading = editable.content;
77+
$node.off("blur.matrix-row-label").on("blur.matrix-row-label", () => {
78+
const rowId = $node.data("fb-matrix-row-id");
79+
const row = findAxisItem(this.data.rows, rowId);
80+
81+
if (!row) {
82+
return;
83+
}
84+
85+
row.label = editable.content;
7386
this.editable.emitSaveRequired();
7487
});
7588
}
7689

7790
bindColumnLabel($node, config) {
7891
const editable = createEditableLabel($node, config);
7992
$node.off("blur.matrix-column-label").on("blur.matrix-column-label", () => {
80-
questionSyncColumnLabel(this, editable.content, $node.data("fb-matrix-column-id"));
93+
const columnId = $node.data("fb-matrix-column-id");
94+
const column = findAxisItem(this.data.columns, columnId);
95+
96+
if (!column) {
97+
return;
98+
}
99+
100+
column.label = editable.content;
101+
this.editable.emitSaveRequired();
81102
});
82103
}
83104

@@ -118,6 +139,20 @@ class MatrixQuestion extends Question {
118139
});
119140
}
120141

142+
initialiseDeleteControls() {
143+
this.$node.on("click.matrix-remove-row", SELECTOR_REMOVE_ROW, (event) => {
144+
event.preventDefault();
145+
const rowId = $(event.currentTarget).data("fb-matrix-row-id");
146+
this.removeRow(rowId);
147+
});
148+
149+
this.$node.on("click.matrix-remove-column", SELECTOR_REMOVE_COLUMN, (event) => {
150+
event.preventDefault();
151+
const columnId = $(event.currentTarget).data("fb-matrix-column-id");
152+
this.removeColumn(columnId);
153+
});
154+
}
155+
121156
hasMatrixCellInput() {
122157
let hasInput = false;
123158

@@ -143,72 +178,143 @@ class MatrixQuestion extends Question {
143178

144179
addRow(config) {
145180
const rowId = generateUuid();
146-
const rowLabel = `Row ${this._rowCount + 1}`;
181+
const rowLabel = `Row ${Array.isArray(this.data.rows) ? this.data.rows.length + 1 : 1}`;
147182

148183
if (!Array.isArray(this.data.rows)) {
149184
this.data.rows = [];
150185
}
151186

152187
this.data.rows.push({ id: rowId, label: rowLabel });
153-
this._rowCount += 1;
154188

155189
const $row = $('<tr class="govuk-table__row"></tr>').attr("data-fb-matrix-row-id", rowId);
156-
const $label = $('<th scope="row" class="govuk-table__header" data-fb-matrix-row-label></th>')
157-
.attr("data-fb-matrix-row-id", rowId)
158-
.text(rowLabel);
159-
160-
$row.append($label);
190+
$row.append(this.createRowHeader(rowId, rowLabel));
161191

162-
Array(this.data.columns || []).forEach((column) => {
163-
$row.append(this.createCell(rowId, column.id));
192+
const columnIds = this.currentColumnIds();
193+
columnIds.forEach((columnId) => {
194+
$row.append(this.createCell(rowId, columnId));
164195
});
165196

166197
this.$node.find(SELECTOR_BODY).append($row);
167-
this.bindRowLabel($label, config);
198+
this.bindRowLabel($row.find(SELECTOR_ROW_LABEL), config);
168199
this.editable.emitSaveRequired();
169200
}
170201

171202
addColumn(config) {
172203
const columnId = generateUuid();
173-
const columnLabel = `Option ${this._columnCount + 1}`;
204+
const columnLabel = `Option ${Array.isArray(this.data.columns) ? this.data.columns.length + 1 : 1}`;
174205

175206
if (!Array.isArray(this.data.columns)) {
176207
this.data.columns = [];
177208
}
178209

179210
this.data.columns.push({ id: columnId, label: columnLabel });
180-
this._columnCount += 1;
181-
182-
const $header = $('<th scope="col" class="govuk-table__header" data-fb-matrix-column-label></th>')
183-
.attr("data-fb-matrix-column-id", columnId)
184-
.text(columnLabel);
185211

212+
const $header = this.createColumnHeader(columnId, columnLabel);
186213
this.$node.find(SELECTOR_HEADER_ROW).append($header);
187-
this.bindColumnLabel($header, config);
214+
this.bindColumnLabel($header.find(SELECTOR_COLUMN_LABEL), config);
188215

189216
this.$node.find("tbody tr").each((_, rowNode) => {
190217
const $row = $(rowNode);
191-
const rowId = $row.data("fb-matrix-row-id") || $row.find(SELECTOR_ROW_LABEL).data("fb-matrix-row-id");
218+
const rowId = $row.data("fb-matrix-row-id");
192219
$row.append(this.createCell(rowId, columnId));
193220
});
194221

195222
this.editable.emitSaveRequired();
196223
}
197224

225+
removeRow(rowId) {
226+
if (!rowId || !Array.isArray(this.data.rows)) {
227+
return;
228+
}
229+
230+
if (this.data.rows.length <= 1) {
231+
return;
232+
}
233+
234+
this.data.rows = this.data.rows.filter((row) => row.id !== rowId);
235+
this.$node.find(`tr[data-fb-matrix-row-id="${rowId}"]`).remove();
236+
this.editable.emitSaveRequired();
237+
}
238+
239+
removeColumn(columnId) {
240+
if (!columnId || !Array.isArray(this.data.columns)) {
241+
return;
242+
}
243+
244+
if (this.data.columns.length <= 1) {
245+
return;
246+
}
247+
248+
this.data.columns = this.data.columns.filter((column) => column.id !== columnId);
249+
this.$node.find(`${SELECTOR_HEADER_ROW} th[data-fb-matrix-column-id="${columnId}"]`).remove();
250+
this.$node.find(`td[data-fb-matrix-column-id="${columnId}"]`).remove();
251+
this.editable.emitSaveRequired();
252+
}
253+
198254
renderMatrixCells() {
255+
const columnIds = this.currentColumnIds();
256+
199257
this.$node.find("tbody tr").each((_, rowNode) => {
200258
const $row = $(rowNode);
201-
const rowId = $row.data("fb-matrix-row-id") || $row.find(SELECTOR_ROW_LABEL).data("fb-matrix-row-id");
259+
const rowId = $row.data("fb-matrix-row-id");
202260

203-
$row.find("td").remove();
204-
Array(this.data.columns || []).forEach((column) => {
205-
$row.append(this.createCell(rowId, column.id));
261+
$row.find("td[data-fb-matrix-column-id]").remove();
262+
columnIds.forEach((columnId) => {
263+
$row.append(this.createCell(rowId, columnId));
206264
});
207265
});
208266
}
209267

268+
currentColumnIds() {
269+
const ids = this.$node.find(`${SELECTOR_HEADER_ROW} th[data-fb-matrix-column-id]`).map((_, node) => {
270+
const value = $(node).data("fb-matrix-column-id");
271+
return value || null;
272+
}).get().filter(Boolean);
273+
274+
if (ids.length > 0) {
275+
return ids;
276+
}
277+
278+
return Array(this.data.columns || []).map((column) => column.id);
279+
}
280+
281+
createColumnHeader(columnId, columnLabel) {
282+
const $header = $('<th scope="col" class="govuk-table__header"></th>')
283+
.attr("data-fb-matrix-column-id", columnId);
284+
285+
$header.append(
286+
$('<span data-fb-matrix-column-label></span>')
287+
.attr("data-fb-matrix-column-id", columnId)
288+
.text(columnLabel)
289+
);
290+
291+
$header.append(
292+
$('<button type="button" class="govuk-link govuk-!-margin-left-1 govuk-!-font-size-16" data-fb-matrix-remove-column>Delete</button>')
293+
.attr("data-fb-matrix-column-id", columnId)
294+
);
295+
296+
return $header;
297+
}
298+
299+
createRowHeader(rowId, rowLabel) {
300+
const $header = $('<th scope="row" class="govuk-table__header"></th>');
301+
302+
$header.append(
303+
$('<span data-fb-matrix-row-label></span>')
304+
.attr("data-fb-matrix-row-id", rowId)
305+
.text(rowLabel)
306+
);
307+
308+
$header.append(
309+
$('<button type="button" class="govuk-link govuk-!-margin-left-1 govuk-!-font-size-16" data-fb-matrix-remove-row>Delete</button>')
310+
.attr("data-fb-matrix-row-id", rowId)
311+
);
312+
313+
return $header;
314+
}
315+
210316
createCell(rowId, columnId) {
211-
const $cell = $('<td class="govuk-table__cell"></td>');
317+
const $cell = $('<td class="govuk-table__cell"></td>').attr("data-fb-matrix-column-id", columnId);
212318

213319
if (this.data.mode === "numeric") {
214320
$cell.append(
@@ -217,8 +323,9 @@ class MatrixQuestion extends Question {
217323
);
218324
} else {
219325
$cell.append(
220-
$('<input type="radio" disabled>')
326+
$('<input type="checkbox" disabled>')
221327
.attr("name", `answers[${this.data.name}][${rowId}]`)
328+
.attr("data-fb-matrix-selection-row-id", rowId)
222329
.val(columnId)
223330
);
224331
}
@@ -227,26 +334,6 @@ class MatrixQuestion extends Question {
227334
}
228335
}
229336

230-
function questionSyncRowLabel(question, label, rowId) {
231-
const row = findAxisItem(question.data.rows, rowId);
232-
if (!row) {
233-
return;
234-
}
235-
236-
row.label = label;
237-
question.editable.emitSaveRequired();
238-
}
239-
240-
function questionSyncColumnLabel(question, label, columnId) {
241-
const column = findAxisItem(question.data.columns, columnId);
242-
if (!column) {
243-
return;
244-
}
245-
246-
column.label = label;
247-
question.editable.emitSaveRequired();
248-
}
249-
250337
function createEditableLabel($node, config) {
251338
const existing = $node.data("instance");
252339
if (existing) {

config/publisher/cloud_platform/deployment.yaml.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ spec:
7575
envFrom:
7676
- configMapRef:
7777
name: <%= config_map_name %>
78-
image: ghcr.io/cabinetoffice/fb-runner:branch-feature-deploy-37e2667
78+
image: ghcr.io/cabinetoffice/fb-runner:branch-feature-deploy-937b775
7979
imagePullPolicy: Always
8080
ports:
8181
- containerPort: <%= container_port %>

0 commit comments

Comments
 (0)