Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement app settings #20

Merged
merged 6 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.1.1] - 2023-10-16
### Added
- ui: refactor BaseModal to allow more configuration props
- ui: implement AppTimeSettingsModal, to set time app format
- ui: implement AppDateSettingsModal, to set date app format
### Changed
- ui: make cards' body font smaller
### Fixed
- ui: bugfix http post method recursion in api module

## [0.1.0] - 2023-10-15
### Added
- Initial release

[Unreleased]: https://github.com/awtrix-light/hub/compare/v0.1.0...HEAD
[Unreleased]: https://github.com/awtrix-light/hub/compare/v0.1.1...HEAD
[1.1.0]: https://github.com/awtrix-light/hub/compare/v0.1.0...v0.1.1
[0.1.0]: https://github.com/awtrix-light/hub/releases/tag/v0.1.0
2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "awtrix-light-hub-ui",
"version": "0.1.0",
"version": "0.1.1",
"private": true,
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion ui/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function post(url: string, data: Record<string, unknown>): Promise<Respon

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function postJ(url: string, data: Record<string, unknown>): Promise<any> {
return postJ(url, data).then((resp) => resp.json());
return post(url, data).then((resp) => resp.json());
}

export function postB(url: string, data: Record<string, unknown>): Promise<boolean> {
Expand Down
124 changes: 124 additions & 0 deletions ui/src/components/awtrix/AppDateSettingsModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<template>
<BaseModal ref="modal" :scrollable="false" @close="$emit('close')">
<template v-slot:title>
<div class="d-flex align-items-center">
<i class="bi bi-calendar-date fs-4 pe-2" /> Date App Settings
</div>
</template>
<template v-slot:body>
<div class="row mb-3">
<div class="col-4">
<span class="align-middle">Format:</span>
</div>
<div class="col-8">
<div class="input-group">
<input type="text" class="form-control form-control-sm" v-model="format">
<CDropdown v-if="nodeStore.activeNode" placement="bottom-end" class="me-2">
<CDropdownToggle size="sm" class="btn-outline-secondary">
<i class="bi bi-list" />
</CDropdownToggle>
<CDropdownMenu>
<CListGroup>
<button
v-for="fp in formatPresets"
:key="fp.format"
class="dropdown-item list-group-item list-group-item-action d-flex justify-content-between"
:class="{ active: fp.format === format }"
type="button"
@click="format = fp.format">
{{ fp.format }}
<small class="text-muted ms-5">{{ fp.example }}</small>
</button>
</CListGroup>
</CDropdownMenu>
</CDropdown>
</div>
</div>
</div>
</template>
<template v-slot:footer>
<button type="button" class="btn btn-light" @click="close">Close</button>
<button type="button" class="btn btn-primary" @click="save">Save</button>
</template>
</BaseModal>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { mapStores } from 'pinia';
import {
CDropdown,
CDropdownToggle,
CDropdownMenu,
CListGroup,
} from '@coreui/vue';
import BaseModal from '@/components/coreui/BaseModal.vue';
import { useNodeStore } from '@/stores/node';
import { useAwtrixStore } from '@/stores/awtrix';

export default defineComponent({
name: 'AppDateSettingsModal',
emits: ['close', 'toast'],
components: {
CDropdown,
CDropdownToggle,
CDropdownMenu,
CListGroup,
BaseModal,
},
data() {
return {
format: ref<string>(''),
formatPresets: [
{ format: '%d.%m.%y', example: '16.04.22' },
{ format: '%d.%m', example: '16.04' },
{ format: '%y-%m-%d', example: '22-04-16' },
{ format: '%m-%d-%y', example: '04-16-22' },
{ format: '%m-%d', example: '04-16' },
{ format: '%m/%d/%y', example: '04/16/22' },
{ format: '%m/%d', example: '04/16' },
{ format: '%d/%m/%y', example: '16/04/22' },
{ format: '%d/%m', example: '16/04' },
],
};
},
computed: {
...mapStores(
useNodeStore, // sets this.nodeStore
useAwtrixStore, // sets this.awtrixStore
),
},
methods: {
close() {
(this.$refs.modal as typeof BaseModal).close();
},
save() {
this.awtrixStore.setSetting('DFORMAT', this.format).then((success: boolean) => {
if (!success) {
this.$emit('toast', { title: 'Error', body: 'New date format is not saved :-(' });
}
});
},
},
mounted() {
this.nodeStore.init().then(() => {
this.format = this.awtrixStore.settings?.DFORMAT || '';
});
},
});
</script>

<style scoped>
.dropdown-menu {
--cui-dropdown-border-width: 0;
padding-top: 0;
padding-bottom: 0;
}
.list-group {
max-height: 260px;
overflow-y: scroll;
}
.list-group-item.active .text-muted {
color: var(--cui-list-group-active-color,rgba(255,255,255,.87)) !important;
}
</style>
126 changes: 126 additions & 0 deletions ui/src/components/awtrix/AppTimeSettingsModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<template>
<BaseModal ref="modal" :scrollable="false" @close="$emit('close')">
<template v-slot:title>
<div class="d-flex align-items-center">
<i class="bi bi-clock fs-4 pe-2" /> Time App Settings
</div>
</template>
<template v-slot:body>
<div class="row mb-3">
<div class="col-4">
<span class="align-middle">Format:</span>
</div>
<div class="col-8">
<div class="input-group">
<input type="text" class="form-control form-control-sm" v-model="format">
<CDropdown v-if="nodeStore.activeNode" placement="bottom-end" class="me-2">
<CDropdownToggle size="sm" class="btn-outline-secondary">
<i class="bi bi-list" />
</CDropdownToggle>
<CDropdownMenu>
<CListGroup>
<button
v-for="fp in formatPresets"
:key="fp.format"
class="dropdown-item list-group-item list-group-item-action"
:class="{ active: fp.format === format }"
type="button"
@click="format = fp.format">
<div class="d-flex justify-content-between">
<span>{{ fp.format }}</span>
<small class="text-muted ms-5">{{ fp.example }}</small>
</div>
<span v-if="fp.blinking" class="badge rounded-pill text-bg-light">blinking</span>
</button>
</CListGroup>
</CDropdownMenu>
</CDropdown>
</div>
</div>
</div>
</template>
<template v-slot:footer>
<button type="button" class="btn btn-light" @click="close">Close</button>
<button type="button" class="btn btn-primary" @click="save">Save</button>
</template>
</BaseModal>
</template>

<script lang="ts">
import { defineComponent, ref } from 'vue';
import { mapStores } from 'pinia';
import {
CDropdown,
CDropdownToggle,
CDropdownMenu,
CListGroup,
} from '@coreui/vue';
import BaseModal from '@/components/coreui/BaseModal.vue';
import { useNodeStore } from '@/stores/node';
import { useAwtrixStore } from '@/stores/awtrix';

export default defineComponent({
name: 'AppTimeSettingsModal',
emits: ['close', 'toast'],
components: {
CDropdown,
CDropdownToggle,
CDropdownMenu,
CListGroup,
BaseModal,
},
data() {
return {
format: ref<string>(''),
formatPresets: [
{ format: '%H:%M:%S', example: '13:30:45' },
{ format: '%l:%M:%S', example: '1:30:45 ' },
{ format: '%H:%M', example: '13:30' },
{ format: '%H %M', example: '13.30', blinking: true },
{ format: '%l:%M', example: '1:30' },
{ format: '%l %M', example: '1:30', blinking: true },
{ format: '%l:%M %p', example: '1:30 PM' },
{ format: '%l %M %p', example: '1:30 PM', blinking: true },
],
};
},
computed: {
...mapStores(
useNodeStore, // sets this.nodeStore
useAwtrixStore, // sets this.awtrixStore
),
},
methods: {
close() {
(this.$refs.modal as typeof BaseModal).close();
},
save() {
this.awtrixStore.setSetting('TFORMAT', this.format).then((success: boolean) => {
if (!success) {
this.$emit('toast', { title: 'Error', body: 'New time format is not saved :-(' });
}
});
},
},
mounted() {
this.nodeStore.init().then(() => {
this.format = this.awtrixStore.settings?.TFORMAT || '';
});
},
});
</script>

<style scoped>
.dropdown-menu {
--cui-dropdown-border-width: 0;
padding-top: 0;
padding-bottom: 0;
}
.list-group {
max-height: 260px;
overflow-y: scroll;
}
.list-group-item.active .text-muted {
color: var(--cui-list-group-active-color,rgba(255,255,255,.87)) !important;
}
</style>
2 changes: 1 addition & 1 deletion ui/src/components/awtrix/DisplayCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@change="awtrixStore.toggleDisplay">
</div>
</div>
<div class="card-body">
<div class="card-body small">
<div class="d-flex justify-content-between align-items-center">
<span class="d-flex align-items-center text-muted">
<i class="bi bi-brightness-high fs-4 pe-2" />
Expand Down
Loading