web: Add timestamp display format to measure configuration.

This commit is contained in:
Jonathan Bernard 2020-03-14 22:45:59 -05:00
parent cf69ff2fa1
commit e9de9aebf3
10 changed files with 101 additions and 17 deletions

8
web/package-lock.json generated
View File

@ -1059,6 +1059,14 @@
"@types/lodash": "*"
}
},
"@types/lodash.omit": {
"version": "4.5.6",
"resolved": "https://registry.npmjs.org/@types/lodash.omit/-/lodash.omit-4.5.6.tgz",
"integrity": "sha512-KXPpOSNX2h0DAG2w7ajpk7TXvWF28ZHs5nJhOJyP0BQHkehgr948RVsToItMme6oi0XJkp19CbuNXkIX8FiBlQ==",
"requires": {
"@types/lodash": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",

View File

@ -18,6 +18,7 @@
"@types/lodash.assign": "^4.2.6",
"@types/lodash.findindex": "^4.6.6",
"@types/lodash.merge": "^4.6.6",
"@types/lodash.omit": "^4.5.6",
"apexcharts": "^3.15.6",
"axios": "^0.18.1",
"js-cookie": "^2.2.1",

View File

@ -2,9 +2,11 @@
<fieldset>
<div>
<label for=measureType>Type</label>
<span v-if=measureExists>{{value.type}}</span>
<select
:disabled=disabled
name=measureType
v-if="!measureExists"
v-model=value.type>
<option value=simple>Simple</option>
<option value=text>Text</option>
@ -14,6 +16,25 @@
<label for=measureIsVisible>Show by default.</label>
<input type=checkbox v-model=value.isVisible :disabled=disabled />
</div>
<div>
<label for=timestampDisplayFormat>Timestamp Format</label>
<select
v-on:change=formatSelectionChanged
:disabled=disabled
v-model=selectedFormat
name=timestampDisplayFormat>
<option v-for="fmtStr in formatStrings"
:value=fmtStr>{{now.format(fmtStr)}}</option>
<option value="custom">Custom</option>
</select>
</div>
<div v-if="selectedFormat === 'custom'">
<label for=timestampCustomDisplayFormat>
Custom Timestamp Format
(<a href="https://momentjs.com/docs/#/displaying/format/">see formatting options</a>)
</label>
<input type=text v-model=value.timestampDisplayFormat />
</div>
<TextMeasureConfigForm v-model=value v-show="value.type === 'text'" :disabled=disabled />
</fieldset>
</template>

View File

@ -2,6 +2,7 @@ import { Component, Emit, Prop, Vue, Watch } from 'vue-property-decorator';
import { logService } from '@/services/logging';
import { Measure, MeasureConfig } from '@/models';
import TextMeasureConfigForm from './TextMeasureConfigForm.vue';
import moment from 'moment';
@Component({
components: {
@ -11,12 +12,41 @@ import TextMeasureConfigForm from './TextMeasureConfigForm.vue';
export class MeasureConfigForm extends Vue {
@Prop({}) public value!: MeasureConfig;
@Prop({}) public disabled: boolean = false;
@Prop({}) public measureExists: boolean = false;
public now = moment();
public formatStrings = [
'l',
'L',
'll',
'LL',
'lll',
'LLL',
'llll',
'LLLL',
'Y-MM-DD',
'Y-MM-DDTHH:mm',
'Y-MM-DDTHH:mm:ss',
'Y-MM-DDTHH:mm:ss.SSSZZ',
'MM/DD',
'MMM Do',
'HH:mm',
'hh:mmA'
];
private selectedFormat: string = 'l';
@Watch('value', { immediate: true, deep: true })
@Emit('input')
private onConfigChanged(newVal: MeasureConfig, oldVal: MeasureConfig) {
return newVal;
}
private formatSelectionChanged() {
if (this.selectedFormat !== 'custom') {
this.value.timestampDisplayFormat = this.selectedFormat;
}
}
}
export default MeasureConfigForm;

View File

@ -1,10 +1,9 @@
import { Component, Prop, Vue } from 'vue-property-decorator';
import { Measure, MeasureConfig, MeasureType, Measurement, MeasurementMeta } from '@/models';
import moment from 'moment';
import assign from 'lodash.assign';
import { library } from '@fortawesome/fontawesome-svg-core';
import { faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { byTimestampComparator } from '@/util';
import { byTimestampComparator, formatTS } from '@/util';
library.add(faPencilAlt);
@ -13,8 +12,6 @@ export class SimpleDetails extends Vue {
@Prop() private measure!: Measure<MeasureConfig>;
@Prop() private measurements!: Array<Measurement<MeasurementMeta>>;
// private newMeasurement;
private moment = moment;
private chartOptions = {
markers: { size: 6 },
noData: { text: 'no data',
@ -37,7 +34,7 @@ export class SimpleDetails extends Vue {
private get measurementTableData() {
return (this.measurements || []).map((m) => {
return assign({}, m, {
tsDisplay: moment(m.timestamp).format('MMM Do, HH:mm'),
tsDisplay: formatTS(this.measure, m),
tsSort: m.timestamp.toISOString()
});
});

1
web/src/models.d.ts vendored
View File

@ -17,6 +17,7 @@ export interface LoginSubmit {
export interface MeasureConfig {
type: MeasureType;
isVisible: boolean;
timestampDisplayFormat: string;
}
export interface TextMeasureConfig extends MeasureConfig {

View File

@ -2,7 +2,8 @@
button,
.btn,
.btn-action {
.btn-action,
.btn-icon {
border: 0;
border-radius: .25em;
cursor: pointer;
@ -14,14 +15,27 @@ button,
a { text-decoration: none; }
}
.btn, .btn-icon { color: $fg-primary; }
.btn-icon {
border-radius: 1em;
padding: .5em;
margin: 0 .5em;
&:hover, &:focus {
background-color: darken($bg-primary, 20%);
}
}
.btn-action {
background-color: $color2;
color: $color3;
cursor: pointer;
position: relative;
&:hover {
background-color: darken($color2, 5%);
&:hover, &:focus {
background-color: lighten($color2, 20%);
}
}

View File

@ -1,7 +1,25 @@
import { Measurement, MeasurementMeta } from '@/models';
import { Measure, MeasureConfig, Measurement, MeasurementMeta } from '@/models';
import moment from 'moment';
export function byTimestampComparator<T extends MeasurementMeta>(
a: Measurement<T>,
b: Measurement<T>): number {
return a.timestamp.getTime() - b.timestamp.getTime();
}
export function formatTS(
m: Measure<MeasureConfig>,
mm: Measurement<MeasurementMeta>
): string {
return moment(mm.timestamp).format(
m.config.timestampDisplayFormat || 'MMM Do');
}
export function slugify(s: string): string {
return s
.toLowerCase()
.replace(/[^\w\s\-]/g, '')
.replace(/\s+/g, '-');
}

View File

@ -1,8 +1 @@
@import '~@/styles/vars';
.header-action .btn {
color: inherit;
margin-left: auto;
margin-right: 2rem;
background-color: none;
}

View File

@ -19,7 +19,8 @@ export class NewMeasure extends Vue {
id: '',
config: {
type: 'simple' as MeasureType,
isVisible: true
isVisible: true,
timestampDisplayFormat: 'l'
},
description: '',
name: '',