Browse Source

HUE-9485 [frontend] Add a short duration format option for the Duration component

Johan Ahlen 5 years ago
parent
commit
e6c5ce2a62

+ 15 - 1
desktop/core/src/desktop/js/components/Duration.test.ts

@@ -15,7 +15,7 @@
 // limitations under the License.
 
 import { shallowMount } from '@vue/test-utils';
-import Duration from './Duration.vue';
+import Duration, { duration } from './Duration.vue';
 
 describe('Duration.vue', () => {
   it('should render', () => {
@@ -27,6 +27,16 @@ describe('Duration.vue', () => {
     expect(wrapper.element).toMatchSnapshot();
   });
 
+  it('should render short format', () => {
+    const wrapper = shallowMount(Duration, {
+      propsData: {
+        value: 1234567890,
+        short: true
+      }
+    });
+    expect(wrapper.element).toMatchSnapshot();
+  });
+
   it('should render 00:00:00 duration', () => {
     const wrapper = shallowMount(Duration, {
       propsData: {
@@ -53,4 +63,8 @@ describe('Duration.vue', () => {
     });
     expect(wrapper.element.firstChild?.textContent).toContain('100:01:01');
   });
+
+  it('should render 4days short duration', () => {
+    expect(duration(1000 * 60 * 60 * 24 * 4, true)).toEqual('4days');
+  });
 });

+ 27 - 4
desktop/core/src/desktop/js/components/Duration.vue

@@ -21,21 +21,44 @@
 </template>
 
 <script lang="ts">
-  import { Duration as LuxonDuration } from 'luxon';
+  import { Duration as LuxonDuration, DurationUnit } from 'luxon';
+  import I18n from '../utils/i18n';
   import Vue from 'vue';
   import Component from 'vue-class-component';
   import { Prop } from 'vue-property-decorator';
 
-  export const duration = (value: number): string =>
-    LuxonDuration.fromMillis(value).toFormat('hh:mm:ss');
+  const SHORT_LIMITS = [
+    { unit: <DurationUnit>'years', postfix: 'year', appendS: true },
+    { unit: <DurationUnit>'days', postfix: 'day', appendS: true },
+    { unit: <DurationUnit>'hours', postfix: 'h', appendS: false },
+    { unit: <DurationUnit>'minutes', postfix: 'm', appendS: false },
+    { unit: <DurationUnit>'seconds', postfix: 's', appendS: false },
+    { unit: <DurationUnit>'milliseconds', postfix: 'ms', appendS: false }
+  ];
+
+  export const duration = (value: number, short?: boolean): string => {
+    const luxonDuration = LuxonDuration.fromMillis(value);
+    if (short) {
+      for (const limit of SHORT_LIMITS) {
+        const val = luxonDuration.as(limit.unit);
+        if (val >= 1) {
+          return Math.floor(val) + I18n(limit.postfix + (limit.appendS && val > 1 ? 's' : ''));
+        }
+      }
+      return `0${I18n('ms')}`;
+    }
+    return luxonDuration.toFormat('hh:mm:ss');
+  };
 
   @Component
   export default class Duration extends Vue {
     @Prop({ required: true })
     value!: number;
+    @Prop({ required: false })
+    short?: boolean;
 
     get duration(): string {
-      return duration(this.value);
+      return duration(this.value, this.short);
     }
   }
 </script>

+ 6 - 0
desktop/core/src/desktop/js/components/__snapshots__/Duration.test.ts.snap

@@ -5,3 +5,9 @@ exports[`Duration.vue should render 1`] = `
   342:56:07
 </span>
 `;
+
+exports[`Duration.vue should render short format 1`] = `
+<span>
+  14days
+</span>
+`;