diff --git a/core/src/inc/Db/MariaDb/DynDnsServerUserService.ts b/core/src/inc/Db/MariaDb/DynDnsServerUserService.ts index b0dc3c7e..ff35c2d8 100644 --- a/core/src/inc/Db/MariaDb/DynDnsServerUserService.ts +++ b/core/src/inc/Db/MariaDb/DynDnsServerUserService.ts @@ -1,3 +1,5 @@ +import {UpdateResult} from 'typeorm'; +import {DateHelper} from '../../Utils/DateHelper.js'; import {DBService} from './DBService.js'; import {DynDnsServerUser} from './Entity/DynDnsServerUser.js'; @@ -23,8 +25,9 @@ export class DynDnsServerUserService extends DBService { } /** - * findByName - * @param name + * Find entry by name. + * @param {string} name + * @returns {DynDnsServerUser | null} */ public findByName(name: string): Promise { return this._repository.findOne({ @@ -34,4 +37,20 @@ export class DynDnsServerUserService extends DBService { }); } + /** + * Set last update for user entry. + * @param {number} id + * @returns {UpdateResult} + */ + public async setLastUpdate(id: number): Promise { + return this._repository + .createQueryBuilder() + .update() + .set({ + last_update: DateHelper.getCurrentDbTime() + }) + .where('id = :id', {id: id}) + .execute(); + } + } \ No newline at end of file diff --git a/ddnsserver/src/Routes/Main/Update.ts b/ddnsserver/src/Routes/Main/Update.ts index 15b32530..4bef6643 100644 --- a/ddnsserver/src/Routes/Main/Update.ts +++ b/ddnsserver/src/Routes/Main/Update.ts @@ -108,6 +108,8 @@ export class Update extends DefaultRoute { } } + await DynDnsServerUserServiceDB.getInstance().setLastUpdate(session.user.userid); + response.status(200).send('OK'); return; } else if (session.user) { diff --git a/frontend/src/inc/Api/DynDnsServer.ts b/frontend/src/inc/Api/DynDnsServer.ts index 7a35a5cc..7dde2a74 100644 --- a/frontend/src/inc/Api/DynDnsServer.ts +++ b/frontend/src/inc/Api/DynDnsServer.ts @@ -1,5 +1,6 @@ import { - DynDnsServerListResponse, + DynDnsServerData, + DynDnsServerListResponse, SchemaDefaultReturn, SchemaDynDnsServerListResponse } from 'flyingfish_schemas'; import {NetFetch} from '../Net/NetFetch'; @@ -10,10 +11,31 @@ import {NetFetch} from '../Net/NetFetch'; export class DynDnsServer { /** - * getUsers + * Return a list with user and domains. + * @returns {DynDnsServerListResponse} */ public static async getUsers(): Promise { return NetFetch.getData('/json/dyndnsserver/list', SchemaDynDnsServerListResponse); } + /** + * Save an dyn dns server entry. + * @param {DynDnsServerData} data + * @returns {boolean} + */ + public static async save(data: DynDnsServerData): Promise { + await NetFetch.postData('/json/dyndnsserver/save', data, SchemaDefaultReturn); + return true; + } + + /** + * Delete a dyn dns server entry. + * @param {DynDnsServerData} data + * @returns {boolean} + */ + public static async delete(data: DynDnsServerData): Promise { + await NetFetch.postData('/json/dyndnsserver/delete', data, SchemaDefaultReturn); + return true; + } + } \ No newline at end of file diff --git a/frontend/src/inc/Pages/DynDnsServer.ts b/frontend/src/inc/Pages/DynDnsServer.ts index 8a33ec4c..741b5265 100644 --- a/frontend/src/inc/Pages/DynDnsServer.ts +++ b/frontend/src/inc/Pages/DynDnsServer.ts @@ -1,18 +1,19 @@ import { Badge, - BadgeType, ButtonMenu, ButtonType, + BadgeType, ButtonClass, ButtonMenu, ButtonType, Card, ContentCol, ContentColSize, - ContentRow, + ContentRow, DialogConfirm, IconFa, - LeftNavbarLink, + LeftNavbarLink, ModalDialogType, Table, Td, Th, Tr } from 'bambooo'; import moment from 'moment/moment'; +import {Domain} from '../Api/Domain'; import {UnauthorizedError} from '../Api/Error/UnauthorizedError'; import {DynDnsServer as DynDnsServerAPI} from '../Api/DynDnsServer'; import {UtilRedirect} from '../Utils/UtilRedirect'; @@ -140,10 +141,67 @@ export class DynDnsServer extends BasePage { btnRMenu.addMenuItem( 'Edit', async(): Promise => { - + this._dynDnsServerDialog.resetValues(); + this._dynDnsServerDialog.setTitle('DynDns Server Account Edit'); + this._dynDnsServerDialog.show(); + + try { + const domains = await Domain.getDomains(); + + if (domains) { + this._dynDnsServerDialog.setDomains(domains.list); + } + } catch (e) { + if (e instanceof UnauthorizedError) { + UtilRedirect.toLogin(); + } + } + + this._dynDnsServerDialog.setId(entry.user.id); + this._dynDnsServerDialog.setDomainSelected(entry.domains); + this._dynDnsServerDialog.setUsername(entry.user.username); }, IconFa.edit ); + + btnRMenu.addDivider(); + + btnRMenu.addMenuItem( + 'Delete', + (): void => { + DialogConfirm.confirm( + 'dnydnsDeleteServer', + ModalDialogType.large, + 'Delete accoun', + 'Are you sure you want to delete the account?', + async(_, dialog) => { + try { + if (await DynDnsServerAPI.delete(entry)) { + this._toast.fire({ + icon: 'success', + title: 'DynDns server account delete success.' + }); + } + } catch (message) { + this._toast.fire({ + icon: 'error', + title: message + }); + } + + dialog.hide(); + + if (this._onLoadTable) { + this._onLoadTable(); + } + }, + undefined, + 'Delete', + ButtonClass.danger + ); + }, + IconFa.trash + ); } } } catch (error) { diff --git a/frontend/src/inc/Pages/DynDnsServer/DynDnsServerEditModal.ts b/frontend/src/inc/Pages/DynDnsServer/DynDnsServerEditModal.ts index 0c52222d..182bc4c7 100644 --- a/frontend/src/inc/Pages/DynDnsServer/DynDnsServerEditModal.ts +++ b/frontend/src/inc/Pages/DynDnsServer/DynDnsServerEditModal.ts @@ -1,4 +1,10 @@ import {Element, FormGroup, InputBottemBorderOnly2, InputType, ModalDialog, ModalDialogType, Multiple} from 'bambooo'; +import {DomainData, DynDnsServerDomain} from 'flyingfish_schemas'; + +/** + * DynDnsServerEditModalButtonClickFn + */ +export type DynDnsServerEditModalButtonClickFn = () => void; export class DynDnsServerEditModal extends ModalDialog { @@ -26,6 +32,12 @@ export class DynDnsServerEditModal extends ModalDialog { */ protected _multipleDomains: Multiple; + /** + * click save fn + * @protected + */ + protected _onSaveClick: DynDnsServerEditModalButtonClickFn|null = null; + /** * constructor * @param elementObject @@ -43,7 +55,132 @@ export class DynDnsServerEditModal extends ModalDialog { const groupDomains = new FormGroup(bodyCard, 'Domains'); this._multipleDomains = new Multiple(groupDomains); - groupDomains.hide(); + + // buttons ----------------------------------------------------------------------------------------------------- + + jQuery('').appendTo(this._footer); + const btnSave = jQuery('').appendTo(this._footer); + + btnSave.on('click', (): void => { + if (this._onSaveClick !== null) { + this._onSaveClick(); + } + }); + } + + /** + * setDomains + * @param domains + */ + public setDomains(domains: DomainData[]): void { + this._multipleDomains.clearValues(); + + for (const domain of domains) { + this._multipleDomains.addValue({ + key: `${domain.id}`, + value: domain.name + }); + } + } + + /** + * setId + * @param id + */ + public setId(id: number): void { + if (id > 0) { + this._inputPassword.setPlaceholder('Leave password blank if you don\'t want to change the password.'); + } else { + this._inputPassword.setPlaceholder(''); + } + + this._id = id; + } + + /** + * getId + */ + public getId(): number|null { + return this._id; + } + + /** + * setDomainSelected + * @param domains + */ + public setDomainSelected(domains: DynDnsServerDomain[]): void { + const list: string[] = []; + + for (const domain of domains) { + list.push(`${domain.id}`); + } + + this._multipleDomains.setValue(list); + } + + /** + * getDomainSelected + */ + public getDomainSelected(): DynDnsServerDomain[] { + const list: DynDnsServerDomain[] = []; + + const values = this._multipleDomains.getValue(); + + for (const value of values) { + list.push({ + id: parseInt(value, 10), + name: '' + }); + } + + return list; + } + + /** + * setUsername + * @param username + */ + public setUsername(username: string): void { + this._inputUsername.setValue(username); + } + + /** + * getUsername + */ + public getUsername(): string { + return this._inputUsername.getValue(); + } + + /** + * setPassword + * @param password + */ + public setPassword(password: string): void { + this._inputPassword.setValue(password); + } + + /** + * getPassword + */ + public getPassword(): string { + return this._inputPassword.getValue(); + } + + /** + * resetValues + */ + public resetValues(): void { + this._multipleDomains.setValue([]); + this._inputUsername.setValue(''); + this._inputPassword.setValue(''); + } + + /** + * setOnSave + * @param onSave + */ + public setOnSave(onSave: DynDnsServerEditModalButtonClickFn): void { + this._onSaveClick = onSave; } } \ No newline at end of file