]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Unify Tasks and Notifications into a sidebar
authorVolker Theile <vtheile@suse.com>
Thu, 2 Apr 2020 09:03:52 +0000 (11:03 +0200)
committerVolker Theile <vtheile@suse.com>
Thu, 2 Apr 2020 11:18:50 +0000 (13:18 +0200)
Fixes: https://tracker.ceph.com/issues/37402
Signed-off-by: Tiago Melo <tmelo@suse.com>
(cherry picked from commit 7fdb3c1504a96a991041934c8abd6453d762857d)

Conflicts:
  src/pybind/mgr/dashboard/frontend/e2e/cluster/crush-map.po.ts
  src/pybind/mgr/dashboard/frontend/package-lock.json
  src/pybind/mgr/dashboard/frontend/package.json
  src/pybind/mgr/dashboard/frontend/src/app/app.component.html
  src/pybind/mgr/dashboard/frontend/src/app/app.module.ts
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/navigation/navigation.component.html
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.html
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.scss
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/notifications/notifications.component.ts
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.html
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.spec.ts
  src/pybind/mgr/dashboard/frontend/src/app/core/navigation/task-manager/task-manager.component.ts
  src/pybind/mgr/dashboard/frontend/src/app/shared/components/components.module.ts
  src/pybind/mgr/dashboard/frontend/src/styles/popover.scss

src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts [new file with mode: 0644]
src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/pipes.module.ts

diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.spec.ts
new file mode 100644 (file)
index 0000000..7241812
--- /dev/null
@@ -0,0 +1,24 @@
+import * as moment from 'moment';
+
+import { DurationPipe } from './duration.pipe';
+
+describe('DurationPipe', () => {
+  const pipe = new DurationPipe();
+
+  it('create an instance', () => {
+    expect(pipe).toBeTruthy();
+  });
+
+  it('transforms seconds into a human readable duration', () => {
+    expect(pipe.transform(0)).toBe('1 second');
+    expect(pipe.transform(6)).toBe('6 seconds');
+    expect(pipe.transform(60)).toBe('1 minute');
+    expect(pipe.transform(600)).toBe('10 minutes');
+    expect(pipe.transform(6000)).toBe('1 hour 40 minutes');
+  });
+
+  it('transforms date into a human readable relative duration', () => {
+    const date = moment().subtract(130, 'seconds');
+    expect(pipe.transform(date, true)).toBe('2 minutes ago');
+  });
+});
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/pipes/duration.pipe.ts
new file mode 100644 (file)
index 0000000..c2b874a
--- /dev/null
@@ -0,0 +1,47 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+import * as moment from 'moment';
+
+@Pipe({
+  name: 'duration',
+  pure: false
+})
+export class DurationPipe implements PipeTransform {
+  transform(date: any, isRelative = false): string {
+    if (isRelative) {
+      return moment(date).fromNow();
+    } else {
+      return this._forHumans(date);
+    }
+  }
+
+  /**
+   * Translates seconds into human readable format of seconds, minutes, hours, days, and years
+   * source: https://stackoverflow.com/a/34270811
+   *
+   * @param  {number} seconds The number of seconds to be processed
+   * @return {string}         The phrase describing the the amount of time
+   */
+  _forHumans(seconds: number): string {
+    const levels = [
+      [`${Math.floor(seconds / 31536000)}`, 'years'],
+      [`${Math.floor((seconds % 31536000) / 86400)}`, 'days'],
+      [`${Math.floor((seconds % 86400) / 3600)}`, 'hours'],
+      [`${Math.floor((seconds % 3600) / 60)}`, 'minutes'],
+      [`${Math.floor(seconds % 60)}`, 'seconds']
+    ];
+    let returntext = '';
+
+    for (let i = 0, max = levels.length; i < max; i++) {
+      if (levels[i][0] === '0') {
+        continue;
+      }
+      returntext +=
+        ' ' +
+        levels[i][0] +
+        ' ' +
+        (levels[i][0] === '1' ? levels[i][1].substr(0, levels[i][1].length - 1) : levels[i][1]);
+    }
+    return returntext.trim() || '1 second';
+  }
+}
index 858ee744c70bcbb860e77537f3723de383921e32..6e96dd1f30a296b2f3c8c83ae6221c8a1a284a2e 100644 (file)
@@ -8,6 +8,7 @@ import { CephShortVersionPipe } from './ceph-short-version.pipe';
 import { DimlessBinaryPerSecondPipe } from './dimless-binary-per-second.pipe';
 import { DimlessBinaryPipe } from './dimless-binary.pipe';
 import { DimlessPipe } from './dimless.pipe';
+import { DurationPipe } from './duration.pipe';
 import { EmptyPipe } from './empty.pipe';
 import { EncodeUriPipe } from './encode-uri.pipe';
 import { FilterPipe } from './filter.pipe';
@@ -48,7 +49,8 @@ import { UpperFirstPipe } from './upper-first.pipe';
     NotAvailablePipe,
     IopsPipe,
     UpperFirstPipe,
-    RbdConfigurationSourcePipe
+    RbdConfigurationSourcePipe,
+    DurationPipe
   ],
   exports: [
     BooleanTextPipe,
@@ -72,7 +74,8 @@ import { UpperFirstPipe } from './upper-first.pipe';
     NotAvailablePipe,
     IopsPipe,
     UpperFirstPipe,
-    RbdConfigurationSourcePipe
+    RbdConfigurationSourcePipe,
+    DurationPipe
   ],
   providers: [
     BooleanTextPipe,