Skip to content

Commit

Permalink
Styling and error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
droberts-ctrlo committed Nov 26, 2024
1 parent 12c606a commit d852b03
Show file tree
Hide file tree
Showing 11 changed files with 72 additions and 67 deletions.
11 changes: 1 addition & 10 deletions src/frontend/components/button/lib/common.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import "../../../testing/globals.definitions";
import {layoutId, recordId, table_key} from "./common";
import {layoutId, recordId} from "./common";

describe("Common button tests",()=>{
it("should populate table_key",()=>{
expect(table_key()).toBe("linkspace-record-change-undefined-0"); // Undefiined because $('body').data('layout-identifier') is not defined
});

it("should have a layoutId", ()=>{
$('body').data('layout-identifier', 'layoutId');
expect(layoutId()).toBe('layoutId');
Expand All @@ -15,9 +11,4 @@ describe("Common button tests",()=>{
expect(isNaN(parseInt(location.pathname.split('/').pop() ?? ""))).toBe(true);
expect(recordId()).toBe(0);
});

it("should populate table_key fully",()=>{
$('body').data('layout-identifier', 'layoutId');
expect(table_key()).toBe("linkspace-record-change-layoutId-0");
});
});
10 changes: 1 addition & 9 deletions src/frontend/components/button/lib/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@ export async function clearSavedFormValues($form: JQuery<HTMLElement>) {
if (!$form || $form.length === 0) return;
const layout = layoutId();
const record = recordId();
const ls = storage();
let item = await ls.getItem(table_key());

if (item) await ls.removeItem(`linkspace-record-change-${layout}-${record}`);
await Promise.all($form.find(".linkspace-field").map(async (_, el) => {
const field_id = $(el).data("column-id");
item = await ls.getItem(`linkspace-column-${field_id}-${layout}-${record}`);
const item = await gadsStorage.getItem(`linkspace-column-${field_id}-${layout}-${record}`);
if (item) gadsStorage.removeItem(`linkspace-column-${field_id}-${layout}-${record}`);
}));
}
Expand All @@ -23,10 +19,6 @@ export function recordId() {
return isNaN(parseInt(location.pathname.split('/').pop())) ? 0 : parseInt(location.pathname.split('/').pop());
}

export function table_key() {
return `linkspace-record-change-${layoutId()}-${recordId()}`;
}

export function storage() {
return location.hostname === 'localhost' || window.test ? localStorage : gadsStorage;
}
20 changes: 20 additions & 0 deletions src/frontend/components/form-group/autosave/_autosave.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,24 @@
background-color: $field-highlight;
border-radius: $input-border-radius;
}
}

li.li-success {
list-style: none;
&::before {
content: '\2713';
color: green;
font-size: 1.5em;
margin-right: 0.5em;
}
}

li.li-error {
list-style: none;
&::before {
content: '\2717';
color: red;
font-size: 1.5em;
margin-right: 0.5em;
}
}
15 changes: 0 additions & 15 deletions src/frontend/components/form-group/autosave/lib/autosave.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,6 @@ describe('AutosaveBase', () => {
document.body.innerHTML = '';
});

it('should return test', () => {
const autosave = new TestAutosave(document.getElementById('test')!);
expect(autosave.test).toBe(true);
});

it('should return layoutId', () => {
const autosave = new TestAutosave(document.getElementById('test')!);
expect(autosave.layoutId).toBe(1);
Expand All @@ -35,14 +30,4 @@ describe('AutosaveBase', () => {
const autosave = new TestAutosave(document.getElementById('test')!);
expect(autosave.recordId).toBe(0);
});

it('should return table_key', () => {
const autosave = new TestAutosave(document.getElementById('test')!);
expect(autosave.table_key).toBe('linkspace-record-change-1-0');
});

it('should return storage', () => {
const autosave = new TestAutosave(document.getElementById('test')!);
expect(autosave.storage).toBe(localStorage);
});
});
10 changes: 1 addition & 9 deletions src/frontend/components/form-group/autosave/lib/autosaveBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ import { Component } from "component";
import gadsStorage from "util/gadsStorage";

export default abstract class AutosaveBase extends Component {
get test() {
return location.hostname === 'localhost' || window.test;
}

constructor(element: HTMLElement) {
super(element);
this.initAutosave();
Expand All @@ -24,12 +20,8 @@ export default abstract class AutosaveBase extends Component {
return isNaN(parseInt(id)) ? 0 : id;
}

get table_key() {
return `linkspace-record-change-${this.layoutId}-${this.recordId}`;
}

get storage() {
return this.test ? localStorage: gadsStorage;
return gadsStorage;
}

columnKey($field:JQuery) {
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/components/form-group/autosave/lib/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class AutosaveComponent extends AutosaveBase {
values = values.map((item) => Number.isInteger(item) ? item : indexed[item]);
}
await self.storage.setItem(column_key, JSON.stringify(values));
await self.storage.setItem(self.table_key, true);
// await self.storage.setItem(self.table_key, true);
} else {
// Delete any values now deleted
let existing = await self.storage.getItem(column_key) ? JSON.parse(await self.storage.getItem(column_key)) : [];
Expand All @@ -50,7 +50,7 @@ class AutosaveComponent extends AutosaveBase {
// deleted, this will need setting if the change was triggered as a
// result of a modal submit for a curval add - everything else will
// have already been saved)
await self.storage.setItem(self.table_key, true);
// await self.storage.setItem(self.table_key, true);
}
});

Expand Down
46 changes: 31 additions & 15 deletions src/frontend/components/form-group/autosave/lib/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,52 @@ class AutosaveModal extends AutosaveBase {
async initAutosave() {
const $modal = $(this.element);
const self = this;
const $form = $('.form-edit');

$modal.find('.btn-js-restore-values').on('click', function (e) {
$modal.find('.btn-js-restore-values').on('click', async function (e) {
e.preventDefault();
const $form = $('.form-edit');

let $list = $("<ul></ul>");
const $body = $modal.find(".modal-body");
$body.html("<p>Restoring values...</p>").append($list);
$form.find('.linkspace-field').each(async function(){
await Promise.all($form.find('.linkspace-field').map(async function () {
const $field = $(this);
const json = await self.storage.getItem(self.columnKey($field));
if (json) {
const values = JSON.parse(json);
await self.storage.getItem(self.columnKey($field)).then(json => {
let values = json ? JSON.parse(json) : undefined;
return values && Array.isArray(values) && values.length ? values : undefined;
}).then(values => {
const $editButton = $field.closest('.card--topic').find('.btn-js-edit');
if($editButton && $editButton.length) $editButton.trigger('click');
if (Array.isArray(values))
if ($editButton && $editButton.length) $editButton.trigger('click');
if (Array.isArray(values) && values.length) {
setFieldValues($field, values);
$field.addClass("field--changed");
const name = $field.data("name");
let $li = $(`<li>Restored ${name}</li>`);
let $li = $(`<li class="li-success">Restored ${name}</li>`);
$list.append($li);
}
}
}).catch(e => {
const name = $field.data("name");
let $li = $(`<li class="li-error">Failed to restore ${name}</li>`);
console.error(e);
$list.append($li);
});
})).then(() => {
$body.append("<p>All values restored.</p>");
}).catch(e => {
$body.append(`<div class="alert alert-danger"><h4>Critical error restoring values</h4><p>${e}</p></div>`);
}).finally(() => {
$modal.find(".modal-footer").find("button:not(.btn-cancel)").hide();
$modal.find(".modal-footer").find(".btn-cancel").text("Close");
});
$body.append("<p>All values restored.</p>");
$modal.find(".modal-footer").find("button:not(.btn-cancel)").hide();
$modal.find(".modal-footer").find(".btn-cancel").text("Close");
});

const item = await self.storage.getItem(this.table_key);

const item = (await Promise.all($form.find('.linkspace-field').map(async (_,field)=> {
if(await self.storage.getItem(self.columnKey($(field)))) {
return true;
}
return false;
}))).includes(true)

if (item){
$modal.modal('show');
$modal.find('.btn-js-delete-values').attr('disabled', 'disabled').hide();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class CurvalModalComponent extends ModalComponent {
}
existing.push(existing_row)
// Store as array for consistency with other field types
await gadsStorage.setItem(parent_key, JSON.stringify(existing), 'local')
await gadsStorage.setItem(parent_key, JSON.stringify(existing))
}

$(this.element).modal('hide')
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/js/lib/set-field-value.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -762,10 +762,10 @@ describe('setFieldValue', () => {
selectWidgetComponent(dom);
document.body.appendChild(dom);
const field = $(dom);
const values = [{"year":2024,"month":11,"day":12,"hour":0,"minute":0,"second":0,"epoch":1731369600}];
const values = [{"year":2024,"month":11,"day":26,"hour":0,"minute":0,"second":0,"epoch":1731369600}];
setFieldValues(field, values);
const input = field.find<HTMLInputElement>('input');
expect(input.val()).toBe('2024-11-12');
expect(input.val()).toBe('2024-11-26');
})
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class EncryptedStorage {
if (!encryptedValue) {
return null;
}
return this.decrypt(encryptedValue, encryptionKey);
return await this.decrypt(encryptedValue, encryptionKey);
}

removeItem(key: string) {
Expand Down
15 changes: 12 additions & 3 deletions src/frontend/js/lib/util/gadsStorage/lib/gadsStorage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { fromJson } from "util/common";
import { EncryptedStorage } from "util/encryptedStorage";

class GadsStorage {
private get test() {
return location.hostname==="localhost";
}

private storage: EncryptedStorage | Storage;
private storageKey: string;

constructor() {
this.storage = location.hostname == "localhost" ? localStorage : EncryptedStorage.instance();
this.test && console.log("Using localStorage");
this.storage = this.test ? localStorage : EncryptedStorage.instance();
}

private async getStorageKey() {
Expand All @@ -19,7 +23,12 @@ class GadsStorage {
}

async setItem(key: string, value: string) {
if(!value || (Array.isArray(fromJson(value)) && value.length === 0)) return;
if(!value || value === "[]") {
if(await this.getItem(key)) {
this.removeItem(key);
}
return;
}
if (!this.storageKey) {
await this.getStorageKey();
}
Expand Down

0 comments on commit d852b03

Please sign in to comment.