Skip to content

Commit 6c459af

Browse files
committed
collapsed rows down into datasets
1 parent 63a4757 commit 6c459af

File tree

17 files changed

+930
-310
lines changed

17 files changed

+930
-310
lines changed

components/dataset/DatasetTable.vue

+45-38
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<hot-table
44
:colHeaders="columnHeaders"
55
:columns="columnFields"
6-
:data="rows.records"
6+
:data="dataset.props.rows"
77
:columnSorting="true"
88
:fixedColumnsLeft="3"
99
:autoWrapCol="true"
@@ -30,7 +30,7 @@
3030
>
3131
</hot-table>
3232
</client-only>
33-
<RowFieldSideBar :row="rows.records[currentRowIndex]" :field="currentRowField" v-model="sidebarVisible" />
33+
<RowFieldSideBar :row="dataset.props.rows[currentRowIndex]" :field="currentRowField" v-model="sidebarVisible" />
3434

3535
</template>
3636

@@ -47,7 +47,6 @@
4747
const sidebarVisible = ref(false);
4848
4949
const props = defineProps({
50-
rows: Object,
5150
dataset: Object,
5251
});
5352
@@ -109,15 +108,15 @@
109108
const promises = [];
110109
for (let change of changes) {
111110
if (rowPos != change[0]) {
112-
promises.push(saveRow(row));
111+
saveRow(row);
113112
rowPos = change[0];
114113
115114
tableRow = hotInstance.getSourceDataAtRow(
116115
hotInstance.toPhysicalRow(rowPos)
117116
);
118-
row = props.rows.find(tableRow.props.id);
117+
row = props.dataset.props.rows.find(r => r.id == tableRow.id);
119118
}
120-
let field = dropProps(change[1]);
119+
let field = change[1];
121120
if (field == 'name') {
122121
validateName(row, change[2]);
123122
} else if (field == 'quantity') {
@@ -126,40 +125,44 @@
126125
// do nothing
127126
} else {
128127
field = getFieldName(field);
129-
row.props = versionFieldHistory(row.props, [field]);
128+
row = versionFieldHistory(row, [field]);
130129
}
131130
}
132-
promises.push(saveRow(row));
133-
await Promise.all(promises);
131+
saveRow(row);
132+
console.log(JSON.stringify(props.dataset.props.rows));
133+
134+
await props.dataset.save('rows');
134135
resumeHotRender();
135136
}
136137
137138
const dropProps = (path) => path.replace(/^props\.(.*)/, '$1');
138139
const getFieldName = (path) => path.replace(/fields\.(.*)\.userValue/, '$1');
139140
140141
const validateName = (row, was) => {
141-
if (row.props.name == '') {
142+
if (row.name == '') {
142143
notify.error('You must give the row a name.');
143144
return;
144145
}
145146
let error = false;
146-
for (let other of props.rows.records) {
147-
if (other.props.name == row.props.name && other.props.id != row.props.id) {
147+
for (let other of props.dataset.props.rows) {
148+
if (other.name == row.name && other.id != row.id) {
148149
error = true;
149150
}
150151
}
151152
if (error) {
152-
notify.error('You already have another row named ' + row.props.name + '.');
153-
row.props.name = was;
153+
notify.error('You already have another row named ' + row.name + '.');
154+
row.name = was;
154155
}
155156
}
156157
157158
const saveRow = (row) => {
158159
if (row) {
159-
row.props = recalcRow(row.props, props.dataset.props.rowSchema);
160-
return row.update();
160+
row = recalcRow(row, props.dataset.props.rowSchema);
161+
//const index = props.dataset.props.rows.findIndex(r => r.id == row.id);
162+
//if (index > -1) {
163+
// props.dataset.props.rows[index] = row;
164+
//}
161165
}
162-
return Promise.resolve();
163166
}
164167
165168
const rowControlsRenderer = (instance, td, rowIndex) => {
@@ -183,9 +186,7 @@
183186
instance.toPhysicalRow(rowIndex)
184187
);
185188
const row = util.findObject(tableRow.id, self.rows);
186-
let newRow = await self.$store.dispatch('duplicateRow', row);
187-
self.$store.dispatch('addRowToServer', newRow);
188-
await props.rows.create(newRow);
189+
await duplicateRow(row);
189190
});
190191
td.appendChild(dupButton);
191192
return td;
@@ -194,23 +195,26 @@
194195
const currentRowIndex = ref(null);
195196
const currentRowField = ref(null);
196197
197-
const openRowFieldSideBar = (row, name) => {
198-
currentRowIndex.value = props.rows.findIndex(row.props.id);
199-
currentRowField.value = name;
198+
const openRowFieldSideBar = (row, fieldName) => {
199+
console.log('row',row )
200+
console.log('name',fieldName)
201+
currentRowIndex.value = props.dataset.props.rows.findIndex((r) => r.id === row.id);
202+
//currentRowIndex.value = row;
203+
currentRowField.value = fieldName;
200204
sidebarVisible.value = true;
201205
}
202206
203207
const columnFields = computed(() => {
204208
const columns = [
205209
{
206-
data: 'props.id',
210+
data: 'id',
207211
type: 'text',
208212
readOnly: true,
209213
renderer: rowControlsRenderer,
210214
},
211-
{ data: 'props.quantity', type: 'numeric' },
215+
{ data: 'quantity', type: 'numeric' },
212216
{
213-
data: 'props.name',
217+
data: 'name',
214218
type: 'text',
215219
columnSorting: {
216220
compareFunctionFactory(sortOrder) {
@@ -230,7 +234,7 @@
230234
231235
for (let field of props.dataset.props.rowFieldOrder || []) {
232236
columns.push({
233-
data: 'props.fields.' + field + '.userValue',
237+
data: 'fields.' + field + '.userValue',
234238
type: 'text',
235239
renderer(instance, td, row) {
236240
//, , col, prop, value, cellProperties)
@@ -245,10 +249,10 @@
245249
let tableRow = instance.getSourceDataAtRow(rowIndex);
246250
if (
247251
tableRow
248-
&& tableRow.props
249-
&& tableRow.props.fields
250-
&& tableRow.props.fields[field]
251-
&& tableRow.props.fields[field].hasError
252+
&& tableRow
253+
&& tableRow.fields
254+
&& tableRow.fields[field]
255+
&& tableRow.fields[field].hasError
252256
) {
253257
td.className = 'border-1 border-red-500';
254258
}
@@ -258,8 +262,8 @@
258262
image.style.height = '30px';
259263
image.style.maxWidth = '100px';
260264
image.style.verticalAlign = 'top';
261-
if (tableRow && tableRow.props && tableRow.props.fields && tableRow.props.fields[field]) {
262-
image.src = tableRow.props.fields[field].calcValue;
265+
if (tableRow && tableRow.fields && tableRow.fields[field]) {
266+
image.src = tableRow.fields[field].calcValue;
263267
}
264268
image.classList.add('border', 'rounded');
265269
div.appendChild(image);
@@ -273,9 +277,9 @@
273277
color.style.margin = 0;
274278
color.style.display = 'inline-block';
275279
color.style.verticalAlign = 'top';
276-
if (tableRow && tableRow.props && tableRow.props.fields && tableRow.props.fields[field]) {
280+
if (tableRow && tableRow.fields && tableRow.fields[field]) {
277281
color.style.backgroundColor =
278-
'#' + tableRow.props.fields[field].calcValue;
282+
'#' + tableRow.fields[field].calcValue;
279283
}
280284
color.classList.add('border-1', 'border-round');
281285
div.appendChild(color);
@@ -364,7 +368,7 @@
364368
const deleteRows = async (rows) => {
365369
let rowNames = [];
366370
for (let row of rows) {
367-
rowNames.push(row.props.name);
371+
rowNames.push(row.name);
368372
}
369373
if (
370374
confirm(
@@ -373,10 +377,13 @@
373377
'?'
374378
)
375379
) {
376-
exportRows(props.dataset, props.rows);
380+
exportRows(props.dataset);
381+
let ids = [];
377382
for (let row of rows) {
378-
row.delete({skipConfirm:true});
383+
ids.push(row.id);
379384
}
385+
props.dataset.props.rows = props.dataset.props.rows.filter((r) => !ids.includes(r.id))
386+
await props.dataset.save('rows');
380387
}
381388
}
382389

components/dataset/RowFieldSideBar.vue

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
<template>
22

33
<Sidebar v-model:visible="val" :header="field" position="right" role="region" :modal="false" :dismissable="false">
4-
<Message v-if="row.props.fields[field].hasError" class="mb-2 mt-0" :closable="false" severity="error">{{row.props.fields[field].error}}</Message>
4+
{{ row }}
5+
6+
<div v-if="row && field && row.fields[field]">
7+
<Message v-if="row.fields[field].hasError" class="mb-2 mt-0" :closable="false" severity="error">{{row.fields[field].error}}</Message>
58

69
<div class="mb-2">
710
<label for="calcValue">Calculated Value</label>
8-
<Textarea id="calcValue" v-model="row.props.fields[field].calcValue" disabled autoResize class="w-full" />
11+
<Textarea id="calcValue" v-model="row.fields[field].calcValue" disabled autoResize class="w-full" />
912
</div>
1013

1114
<div class="mb-2">
1215
<label for="userValue">User Value</label>
13-
<Textarea id="userValue" v-model="row.props.fields[field].userValue" autoResize class="w-full" @change="saveRowFieldHistory(row, field)" @focus="suspendHotRender()" @blur="resumeHotRender()" />
16+
<Textarea id="userValue" v-model="row.fields[field].userValue" autoResize class="w-full" @change="saveRowFieldHistory(row, field)" @focus="suspendHotRender()" @blur="resumeHotRender()" />
1417
</div>
1518

1619
<div>Shortcuts</div>
1720
<div class="flex flex-inline gap-1">
1821
<TemplateFunctions />
19-
<FieldHistory :variables="row.props.fields[field].history" />
22+
<FieldHistory :variables="row.fields[field].history" />
2023
</div>
24+
</div>
2125

2226
</Sidebar>
2327
</template>

components/dataset/toolbar/AddRowsCols.vue

+21-5
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@
3333
</OverlayPanel>
3434
</template>
3535
<script setup>
36+
import { v4 } from 'uuid';
3637
import appendNumberToString from '#ving/utils/appendNumberToString';
3738
const props = defineProps({
3839
dataset: Object,
39-
rows: Object,
4040
});
4141
const toolbarLabels = useToolbarLabels();
4242
const op = ref();
@@ -80,12 +80,28 @@ const makeNameSafe = (userTyped) => {
8080
return safe;
8181
};
8282
83+
const appendNewRows = useAppendNewRows();
84+
const addRow = () => {
85+
let row = { quantity: 1, name : 'Untitled '+Math.random().toString(), fields : {}, id : v4() };
86+
for (const field in props.dataset.props.rowSchema) {
87+
row.fields[field] = formatFieldType(props.dataset.props.rowSchema[field].type, row.fields[field]);
88+
}
89+
if (appendNewRows) {
90+
props.dataset.props.rows.push(row);
91+
}
92+
else {
93+
props.dataset.props.rows.unshift(row);
94+
}
95+
}
96+
97+
8398
const quantityOfRowsToAdd = ref(1);
8499
const addRows = async () => {
85100
suspendHotRender();
86101
for (let i = 0; i < quantityOfRowsToAdd.value; i++) {
87-
await props.rows.create({name: 'Untitled '+Math.random().toString()});
102+
addRow();
88103
}
104+
await props.dataset.save('rows');
89105
toggle();
90106
resumeHotRender();
91107
const appendNewRows = useAppendNewRows();
@@ -98,9 +114,9 @@ const addRows = async () => {
98114
const deleteAllRows = async () => {
99115
if (confirm('Are you sure you want to delete all rows in this dataset?')) {
100116
suspendHotRender();
101-
exportRows(props.dataset, props.rows);
102-
await props.dataset.call('DELETE', props.dataset.links.rows.href);
103-
props.rows.reset();
117+
exportRows(props.dataset);
118+
props.dataset.props.rows = [];
119+
await props.dataset.save('rows');
104120
toggle();
105121
resumeHotRender();
106122
}

composables/dataset/recalcRows.mjs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
export const recalcRows = (rows, schema) => {
2-
let s = schema ? schema : useDataset().props.rowSchema;
3-
for (const record of rows.records) {
4-
record.props = recalcRow(record.props, s);
1+
export const recalcRows = (dataset) => {
2+
let d = dataset ? dataset : useDataset();
3+
for (let row of dataset.props.rows) {
4+
row = recalcRow(row, dataset.props.rowSchema);
55
}
66
}
+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export default async (row, field) => {
2-
versionFieldHistory(row.props, [field]);
3-
row.props = recalcRow(row.props);
4-
await row.save('fields');
2+
versionFieldHistory(row, [field]);
3+
const dataset = useDataset();
4+
row = recalcRow(row, dataset.props.rowSchema);
5+
await dataset.save('rows');
56
}

pages/game/[id]/datasets/[dsid].vue

+13-17
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
<Title>{{ dataset.props?.name }} Dataset Editor</Title>
33
<div class="flex flex-wrap gap-1">
44
<ManageGameVariables :game="game" />
5-
<AddRowsCols :dataset="dataset" :rows="rows" />
5+
<AddRowsCols :dataset="dataset" />
66
<UserPreferences/>
77
<BackToDatasets :game="game" />
88
</div>
99

10-
<DatasetTable :rows="rows" :dataset="dataset"/>
10+
<DatasetTable :dataset="dataset"/>
1111

1212

1313
</template>
@@ -22,33 +22,30 @@ const gameId = useGameId(route.params.id.toString());
2222
const game = useGame();
2323
const datasetId = useDatasetId(route.params.dsid.toString());
2424
const dataset = useDataset();
25-
const appendNewRows = useAppendNewRows();;
26-
const rows = useVingKind({
27-
listApi: `/api/${useRestVersion()}/dataset/${datasetId.value}/rows`,
28-
createApi: `/api/${useRestVersion()}/row`,
29-
query: { includeMeta: true, sortBy: 'name', itemsPerPage: 100 },
30-
newDefaults: { name: '', game: gameId.value, datasetId: datasetId.value },
31-
unshift : !appendNewRows.value,
32-
onEach(record) {
25+
26+
const formatAllRows = () => {
27+
for (let i = 0; i < dataset.props.rows.length; i++) {
3328
for (const field in dataset.props.rowSchema) {
34-
record.props.fields[field] = formatFieldType(dataset.props.rowSchema[field].type, record.props.fields[field]);
29+
dataset.props.rows[i].fields[field] = formatFieldType(dataset.props.rowSchema[field].type, dataset.props.rows[i].fields[field]);
3530
}
36-
record.props = recalcRow(record.props, dataset.props.rowSchema);
3731
}
38-
});
32+
}
33+
3934
await Promise.all([
4035
game.fetch(),
4136
dataset.fetch(),
42-
rows.fetchPropsOptions(),
4337
]);
4438
recalcGameFields(game);
45-
await rows.all();
39+
formatAllRows();
40+
recalcRows(dataset);
41+
42+
4643
4744
const gameTemplateVars = useGameTemplateVars();
4845
const unsubscribeFromGameTemplateVars = gameTemplateVars.$onAction((e) => {
4946
if (e.name == 'set') {
5047
e.after((result) => {
51-
recalcRows(rows, dataset.props.rowSchema);
48+
recalcRows(dataset);
5249
});
5350
}
5451
}
@@ -58,7 +55,6 @@ onBeforeRouteLeave(() => {
5855
unsubscribeFromGameTemplateVars();
5956
game.dispose();
6057
dataset.dispose();
61-
rows.dispose();
6258
});
6359
6460
</script>

0 commit comments

Comments
 (0)