From 6f984ac3f7ae6b8d8dfa617656fc7de6ee975cc7 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 15:14:10 -0500 Subject: [PATCH 001/101] Remove multi-path test for now --- ui/tests/acceptance/task-fs-path-test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 5d32d4196bc..20f31923fd5 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -1,7 +1,7 @@ import { currentURL } from '@ember/test-helpers'; import { Promise } from 'rsvp'; -import { module, test } from 'qunit'; -import { setupApplicationTest } from 'ember-qunit'; +import { module, skip } from 'qunit'; +import { setupApplicationTest, test } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import Path from 'nomad-ui/tests/pages/allocations/task/fs/path'; @@ -21,7 +21,7 @@ module('Acceptance | task fs path', function(hooks) { task = server.schema.taskStates.where({ allocationId: allocation.id }).models[0]; }); - test('visiting /allocations/:allocation_id/:task_name/fs/:path', async function(assert) { + skip('visiting /allocations/:allocation_id/:task_name/fs/:path', async function(assert) { const paths = ['some-file.log', 'a/deep/path/to/a/file.log', '/', 'Unicode™®']; const testPath = async filePath => { From 274d1d687ddd82a6cf596137b7a9affabf46133e Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 15:35:01 -0500 Subject: [PATCH 002/101] Add rudimentary directory listing --- .../allocations/allocation/task/fs/path.js | 22 ++++++++++++++----- .../allocations/allocation/task/fs/path.hbs | 6 +++++ ui/tests/acceptance/task-fs-path-test.js | 12 ++++++++++ ui/tests/pages/allocations/task/fs/path.js | 4 +++- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/ui/app/routes/allocations/allocation/task/fs/path.js b/ui/app/routes/allocations/allocation/task/fs/path.js index b18931215c6..ff301f35ea5 100644 --- a/ui/app/routes/allocations/allocation/task/fs/path.js +++ b/ui/app/routes/allocations/allocation/task/fs/path.js @@ -1,15 +1,25 @@ import Route from '@ember/routing/route'; +import fetch from 'nomad-ui/utils/fetch'; +import RSVP from 'rsvp'; export default Route.extend({ model({ path }) { - return { - path: decodeURIComponent(path), - task: this.modelFor('allocations.allocation.task'), - }; + const decodedPath = decodeURIComponent(path); + const task = this.modelFor('allocations.allocation.task'); + + const allocation = this.modelFor('allocations.allocation'); + + return RSVP.hash({ + path: decodedPath, + task, + ls: fetch(`/v1/client/fs/ls/${allocation.id}?path=${task.name}`).then(response => + response.json() + ), + }); }, - setupController(controller, { path, task }) { + setupController(controller, { path, task, ls }) { this._super(...arguments); - controller.setProperties({ path, model: task }); + controller.setProperties({ path, model: task, ls }); }, }); diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index ce1b3a010f0..fee80139f1d 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -1,4 +1,10 @@ {{partial "allocations/allocation/task/subnav"}}

Path fs route {{path}}

+ +
    + {{#each ls as |entry|}} +
  • {{entry.Name}}
  • + {{/each}} +
\ No newline at end of file diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 20f31923fd5..46a24efe9d1 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -39,4 +39,16 @@ module('Acceptance | task fs path', function(hooks) { return testPath(filePath); }, Promise.resolve()); }); + + test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { + this.server.get('/client/fs/ls/:allocation_id', () => { + return [{ Name: 'jorts' }, { Name: 'jants' }]; + }); + + await Path.visit({ id: allocation.id, name: task.name, path: 'somewhere' }); + + assert.equal(Path.entries.length, 2); + assert.equal(Path.entries[0].text, 'jorts'); + assert.equal(Path.entries[1].text, 'jants'); + }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index d4b7097d26a..80cce99ccf6 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -1,7 +1,9 @@ -import { create, text, visitable } from 'ember-cli-page-object'; +import { collection, create, text, visitable } from 'ember-cli-page-object'; export default create({ visit: visitable('/allocations/:id/:name/fs/:path'), tempTitle: text('h1.title'), + + entries: collection('[data-test-entry]'), }); From 2796b0702fb99df9c038288dbefa343fea412ac6 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:01:27 -0500 Subject: [PATCH 003/101] Add placeholder for file/directory icons --- .../allocations/allocation/task/fs/path.hbs | 10 +++++++++- ui/tests/acceptance/task-fs-path-test.js | 13 +++++++++---- ui/tests/pages/allocations/task/fs/path.js | 8 ++++++-- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index fee80139f1d..2039f26c907 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -4,7 +4,15 @@
    {{#each ls as |entry|}} -
  • {{entry.Name}}
  • +
  • + {{#if entry.IsDir}} + dir + {{else}} + file + {{/if}} + + {{entry.Name}} +
  • {{/each}}
\ No newline at end of file diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 46a24efe9d1..46f10454d70 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -42,13 +42,18 @@ module('Acceptance | task fs path', function(hooks) { test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { this.server.get('/client/fs/ls/:allocation_id', () => { - return [{ Name: 'jorts' }, { Name: 'jants' }]; + return [{ Name: 'jorts' }, { Name: 'jants' }, { Name: 'directory', IsDir: true }]; }); await Path.visit({ id: allocation.id, name: task.name, path: 'somewhere' }); - assert.equal(Path.entries.length, 2); - assert.equal(Path.entries[0].text, 'jorts'); - assert.equal(Path.entries[1].text, 'jants'); + assert.equal(Path.entries.length, 3); + assert.equal(Path.entries[0].name, 'jorts'); + assert.ok(Path.entries[0].isFile); + + assert.equal(Path.entries[1].name, 'jants'); + + assert.equal(Path.entries[2].name, 'directory'); + assert.ok(Path.entries[2].isDirectory); }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index 80cce99ccf6..928a26a24f1 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -1,9 +1,13 @@ -import { collection, create, text, visitable } from 'ember-cli-page-object'; +import { collection, create, isPresent, text, visitable } from 'ember-cli-page-object'; export default create({ visit: visitable('/allocations/:id/:name/fs/:path'), tempTitle: text('h1.title'), - entries: collection('[data-test-entry]'), + entries: collection('[data-test-entry]', { + name: text('[data-test-name]'), + isFile: isPresent('[data-test-file-icon]'), + isDirectory: isPresent('[data-test-directory-icon]'), + }), }); From 5f0e0a970057161fb87894b8075b12518bc021a7 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:07:03 -0500 Subject: [PATCH 004/101] Replace placeholders with Structure icons --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 4 ++-- ui/ember-cli-build.js | 2 +- ui/package.json | 1 + ui/yarn.lock | 5 +++++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 2039f26c907..caefc79048f 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -6,9 +6,9 @@ {{#each ls as |entry|}}
  • {{#if entry.IsDir}} - dir + {{inline-svg 'folder-outline' class='icon'}} {{else}} - file + {{inline-svg 'file-outline' class='icon'}} {{/if}} {{entry.Name}} diff --git a/ui/ember-cli-build.js b/ui/ember-cli-build.js index 6e2fb01c596..cfa0fb99667 100644 --- a/ui/ember-cli-build.js +++ b/ui/ember-cli-build.js @@ -11,7 +11,7 @@ module.exports = function(defaults) { blacklist: isProd ? ['ember-freestyle'] : [], }, svg: { - paths: ['public/images/icons'], + paths: ['node_modules/@hashicorp/structure-icons/dist', 'public/images/icons'], optimize: { plugins: [{ removeViewBox: false }], }, diff --git a/ui/package.json b/ui/package.json index b7cc42fc054..f3c4da55e4a 100644 --- a/ui/package.json +++ b/ui/package.json @@ -29,6 +29,7 @@ "@babel/plugin-proposal-object-rest-spread": "^7.4.3", "@ember/jquery": "^0.6.0", "@ember/optional-features": "^0.7.0", + "@hashicorp/structure-icons": "^1.3.0", "broccoli-asset-rev": "^3.0.0", "bulma": "0.6.1", "core-js": "^2.4.1", diff --git a/ui/yarn.lock b/ui/yarn.lock index ba69e1755b7..515bd9c25e8 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -766,6 +766,11 @@ dependencies: "@glimmer/util" "^0.38.1" +"@hashicorp/structure-icons@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@hashicorp/structure-icons/-/structure-icons-1.3.0.tgz#1c7c1cb43a1c1aa92b073a7aa7956495ae14c3e0" + integrity sha512-wTKpdaAPphEY2kg5QbQTSUlhqLTpBBR1+1dXp4LYTN0PtMSpetyDDDhcSyvKE8i4h2nwPJBRRfeFlE1snaHd7w== + "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" From 875e09c176e1f5ace886232a58fff8e9b454aafb Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:19:50 -0500 Subject: [PATCH 005/101] Change sorting to list directories first --- .../allocations/allocation/task/fs/path.js | 7 +++++++ .../allocations/allocation/task/fs/path.hbs | 15 ++++++++------- ui/tests/acceptance/task-fs-path-test.js | 17 +++++++++++------ 3 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 ui/app/controllers/allocations/allocation/task/fs/path.js diff --git a/ui/app/controllers/allocations/allocation/task/fs/path.js b/ui/app/controllers/allocations/allocation/task/fs/path.js new file mode 100644 index 00000000000..851ee034ef1 --- /dev/null +++ b/ui/app/controllers/allocations/allocation/task/fs/path.js @@ -0,0 +1,7 @@ +import Controller from '@ember/controller'; +import { filterBy } from '@ember/object/computed'; + +export default Controller.extend({ + directories: filterBy('ls', 'IsDir'), + files: filterBy('ls', 'IsDir', false), +}); diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index caefc79048f..1a896205d88 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -3,14 +3,15 @@

    Path fs route {{path}}

      - {{#each ls as |entry|}} + {{#each directories as |entry|}}
    • - {{#if entry.IsDir}} - {{inline-svg 'folder-outline' class='icon'}} - {{else}} - {{inline-svg 'file-outline' class='icon'}} - {{/if}} - + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} +
    • + {{/each}} + {{#each files as |entry|}} +
    • + {{inline-svg 'file-outline' class='icon'}} {{entry.Name}}
    • {{/each}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 46f10454d70..390c20921ae 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -42,18 +42,23 @@ module('Acceptance | task fs path', function(hooks) { test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { this.server.get('/client/fs/ls/:allocation_id', () => { - return [{ Name: 'jorts' }, { Name: 'jants' }, { Name: 'directory', IsDir: true }]; + return [ + { Name: 'jorts', IsDir: false }, + { Name: 'jants', IsDir: false }, + { Name: 'directory', IsDir: true }, + ]; }); await Path.visit({ id: allocation.id, name: task.name, path: 'somewhere' }); assert.equal(Path.entries.length, 3); - assert.equal(Path.entries[0].name, 'jorts'); - assert.ok(Path.entries[0].isFile); - assert.equal(Path.entries[1].name, 'jants'); + assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); + assert.ok(Path.entries[0].isDirectory); - assert.equal(Path.entries[2].name, 'directory'); - assert.ok(Path.entries[2].isDirectory); + assert.equal(Path.entries[1].name, 'jorts'); + assert.ok(Path.entries[1].isFile); + + assert.equal(Path.entries[2].name, 'jants'); }); }); From 1d0c20056dfe4cde1b994bdd2d37b6d0f74abb0a Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:22:37 -0500 Subject: [PATCH 006/101] Convert list to table --- .../allocations/allocation/task/fs/path.hbs | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 1a896205d88..aaab7dfd2b7 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -2,18 +2,27 @@

      Path fs route {{path}}

      -
        + + + + + + {{#each directories as |entry|}} -
      • - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} -
      • + + + {{/each}} {{#each files as |entry|}} -
      • - {{inline-svg 'file-outline' class='icon'}} - {{entry.Name}} -
      • + + + {{/each}} - +
        Name
        + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} +
        + {{inline-svg 'file-outline' class='icon'}} + {{entry.Name}} +
      \ No newline at end of file From 6025edea83b135df783cfe85fd674f422908c20c Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:35:25 -0500 Subject: [PATCH 007/101] Add entry sizes --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 3 +++ ui/tests/acceptance/task-fs-path-test.js | 6 ++++-- ui/tests/pages/allocations/task/fs/path.js | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index aaab7dfd2b7..4612a8333e3 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -6,6 +6,7 @@ Name + Size {{#each directories as |entry|}} @@ -14,6 +15,7 @@ {{inline-svg 'folder-outline' class='icon'}} {{entry.Name}} + {{format-bytes entry.Size}} {{/each}} {{#each files as |entry|}} @@ -22,6 +24,7 @@ {{inline-svg 'file-outline' class='icon'}} {{entry.Name}} + {{format-bytes entry.Size}} {{/each}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 390c20921ae..d8bb3480619 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -43,9 +43,9 @@ module('Acceptance | task fs path', function(hooks) { test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { this.server.get('/client/fs/ls/:allocation_id', () => { return [ - { Name: 'jorts', IsDir: false }, + { Name: 'jorts', IsDir: false, Size: 1919 }, { Name: 'jants', IsDir: false }, - { Name: 'directory', IsDir: true }, + { Name: 'directory', IsDir: true, Size: 3682561 }, ]; }); @@ -55,9 +55,11 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); assert.ok(Path.entries[0].isDirectory); + assert.equal(Path.entries[0].size, '3 MiB'); assert.equal(Path.entries[1].name, 'jorts'); assert.ok(Path.entries[1].isFile); + assert.equal(Path.entries[1].size, '1 KiB'); assert.equal(Path.entries[2].name, 'jants'); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index 928a26a24f1..099d7decc03 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -9,5 +9,7 @@ export default create({ name: text('[data-test-name]'), isFile: isPresent('[data-test-file-icon]'), isDirectory: isPresent('[data-test-directory-icon]'), + + size: text('[data-test-size]'), }), }); From ca2baf3ec2b83f180cdfdbb0621fb6d55d84a428 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:51:09 -0500 Subject: [PATCH 008/101] Add tbody --- .../allocations/allocation/task/fs/path.hbs | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 4612a8333e3..4f7ee61a853 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -9,23 +9,25 @@ Size - {{#each directories as |entry|}} - - - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} - - {{format-bytes entry.Size}} - - {{/each}} - {{#each files as |entry|}} - - - {{inline-svg 'file-outline' class='icon'}} - {{entry.Name}} - - {{format-bytes entry.Size}} - - {{/each}} + + {{#each directories as |entry|}} + + + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} + + {{format-bytes entry.Size}} + + {{/each}} + {{#each files as |entry|}} + + + {{inline-svg 'file-outline' class='icon'}} + {{entry.Name}} + + {{format-bytes entry.Size}} + + {{/each}} + \ No newline at end of file From b8a5c42d6e3a5014d47f525f180b8ed367ec6a11 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 16:53:15 -0500 Subject: [PATCH 009/101] Add file mode to table --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 3 +++ ui/tests/acceptance/task-fs-path-test.js | 6 ++++-- ui/tests/pages/allocations/task/fs/path.js | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 4f7ee61a853..b08e673b7fe 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -7,6 +7,7 @@ Name Size + Mode @@ -17,6 +18,7 @@ {{entry.Name}} {{format-bytes entry.Size}} + {{entry.FileMode}} {{/each}} {{#each files as |entry|}} @@ -26,6 +28,7 @@ {{entry.Name}} {{format-bytes entry.Size}} + {{entry.FileMode}} {{/each}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index d8bb3480619..f186fbb4734 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -43,9 +43,9 @@ module('Acceptance | task fs path', function(hooks) { test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { this.server.get('/client/fs/ls/:allocation_id', () => { return [ - { Name: 'jorts', IsDir: false, Size: 1919 }, + { Name: 'jorts', IsDir: false, Size: 1919, FileMode: '-rw-r--r--' }, { Name: 'jants', IsDir: false }, - { Name: 'directory', IsDir: true, Size: 3682561 }, + { Name: 'directory', IsDir: true, Size: 3682561, FileMode: 'drwxr-xr-x' }, ]; }); @@ -56,10 +56,12 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); assert.ok(Path.entries[0].isDirectory); assert.equal(Path.entries[0].size, '3 MiB'); + assert.equal(Path.entries[0].fileMode, 'drwxr-xr-x'); assert.equal(Path.entries[1].name, 'jorts'); assert.ok(Path.entries[1].isFile); assert.equal(Path.entries[1].size, '1 KiB'); + assert.equal(Path.entries[1].fileMode, '-rw-r--r--'); assert.equal(Path.entries[2].name, 'jants'); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index 099d7decc03..df7cd29145f 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -11,5 +11,6 @@ export default create({ isDirectory: isPresent('[data-test-directory-icon]'), size: text('[data-test-size]'), + fileMode: text('[data-test-file-mode]'), }), }); From 75edb486bcdcc6b925f142a0e8b8233f8c849005 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 17:07:38 -0500 Subject: [PATCH 010/101] Add hardcoded Mirage directory listing --- ui/mirage/config.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 24ddf66618f..35e55bca922 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -312,6 +312,15 @@ export default function() { this.get('/client/allocation/:id/stats', clientAllocationStatsHandler); this.get('/client/fs/logs/:allocation_id', clientAllocationLog); + // FIXME replace with more ORMy mocks? Nesting? Confine to tests only? 🧐 + this.get('/client/fs/ls/:allocation_id', () => { + return [ + { Name: 'jorts', IsDir: false, Size: 1919, FileMode: '-rw-r--r--' }, + { Name: 'jants', IsDir: false }, + { Name: 'directory', IsDir: true, Size: 3682561, FileMode: 'drwxr-xr-x' }, + ]; + }); + this.get('/client/stats', function({ clientStats }, { queryParams }) { const seed = Math.random(); if (seed > 0.8) { From 30e6771e026ba4b31c06987e19de0d06afe7c33f Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 17:07:55 -0500 Subject: [PATCH 011/101] Change files link to include path --- ui/app/templates/allocations/allocation/task/subnav.hbs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/subnav.hbs b/ui/app/templates/allocations/allocation/task/subnav.hbs index d2f78cd6d8d..2716182c3c3 100644 --- a/ui/app/templates/allocations/allocation/task/subnav.hbs +++ b/ui/app/templates/allocations/allocation/task/subnav.hbs @@ -2,6 +2,7 @@
      • {{#link-to "allocations.allocation.task.index" model.allocation model activeClass="is-active"}}Overview{{/link-to}}
      • {{#link-to "allocations.allocation.task.logs" model.allocation model activeClass="is-active"}}Logs{{/link-to}}
      • -
      • {{#link-to "allocations.allocation.task.fs" model.allocation model activeClass="is-active"}}Files{{/link-to}}
      • + {{! FIXME remove hardcoded root path }} +
      • {{#link-to "allocations.allocation.task.fs.path" model.allocation model "%2F" activeClass="is-active"}}Files{{/link-to}}
      From 3726a6df51170cf938535277b3197a82b3e030f6 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Fri, 21 Jun 2019 17:38:51 -0500 Subject: [PATCH 012/101] Add scenario for stable preview demonstration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This doesn’t work in every instance; sometimes when I refresh there’s a failure. I’ll have to tune the models created to eliminate these occasional problems. --- ui/config/environment.js | 2 +- ui/mirage/scenarios/default.js | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/ui/config/environment.js b/ui/config/environment.js index 626a14295d7..eae1b1b72c2 100644 --- a/ui/config/environment.js +++ b/ui/config/environment.js @@ -22,7 +22,7 @@ module.exports = function(environment) { APP: { blockingQueries: true, - mirageScenario: 'smallCluster', + mirageScenario: 'allocationFileExplorer', // FIXME for stable preview links only mirageWithNamespaces: true, mirageWithTokens: true, mirageWithRegions: true, diff --git a/ui/mirage/scenarios/default.js b/ui/mirage/scenarios/default.js index 62c4c427c3c..89f656acb01 100644 --- a/ui/mirage/scenarios/default.js +++ b/ui/mirage/scenarios/default.js @@ -13,6 +13,7 @@ const allScenarios = { allNodeTypes, everyFeature, emptyCluster, + allocationFileExplorer, // FIXME for stable preview links only }; const scenario = getConfigValue('mirageScenario', 'emptyCluster'); @@ -115,6 +116,31 @@ function emptyCluster(server) { server.create('node'); } +function allocationFileExplorer(server) { + server.create('node'); + + const job = server.create('job', { + id: 'a-job', + type: 'service', + activeDeployment: true, + namespaceId: 'default', + createAllocations: false, + }); + + const taskGroup = server.create('task-group', { + name: 'task-group', + createAllocations: false, + shallow: true, + jobId: job.id, + }); + server.create('task', { name: 'task', taskGroup: taskGroup }); + server.create('allocation', 'rescheduled', { + id: '12345', + jobId: job.id, + taskGroup: taskGroup.name, + }); +} + // Behaviors function createTokens(server) { From 71c8c82ff97997dab0dfc217d6c233e0155ee1de Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 09:18:37 -0500 Subject: [PATCH 013/101] Add empty commit From ad5621bf42df588b0bb1b90855ec896d2013de21 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 10:49:48 -0500 Subject: [PATCH 014/101] Add last modified column --- .../allocations/allocation/task/fs/path.hbs | 3 +++ ui/tests/acceptance/task-fs-path-test.js | 23 +++++++++++++++++-- ui/tests/pages/allocations/task/fs/path.js | 1 + 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index b08e673b7fe..73b50e16be3 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -8,6 +8,7 @@ Name Size Mode + Last Modified @@ -19,6 +20,7 @@ {{format-bytes entry.Size}} {{entry.FileMode}} + {{moment-from-now entry.ModTime}} {{/each}} {{#each files as |entry|}} @@ -29,6 +31,7 @@ {{format-bytes entry.Size}} {{entry.FileMode}} + {{moment-from-now entry.ModTime}} {{/each}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index f186fbb4734..7cf7fa29617 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -4,6 +4,7 @@ import { module, skip } from 'qunit'; import { setupApplicationTest, test } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import Path from 'nomad-ui/tests/pages/allocations/task/fs/path'; +import moment from 'moment'; let allocation; let task; @@ -43,9 +44,25 @@ module('Acceptance | task fs path', function(hooks) { test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { this.server.get('/client/fs/ls/:allocation_id', () => { return [ - { Name: 'jorts', IsDir: false, Size: 1919, FileMode: '-rw-r--r--' }, + { + Name: 'jorts', + IsDir: false, + Size: 1919, + FileMode: '-rw-r--r--', + ModTime: moment() + .subtract(2, 'day') + .format(), + }, { Name: 'jants', IsDir: false }, - { Name: 'directory', IsDir: true, Size: 3682561, FileMode: 'drwxr-xr-x' }, + { + Name: 'directory', + IsDir: true, + Size: 3682561, + FileMode: 'drwxr-xr-x', + ModTime: moment() + .subtract(1, 'year') + .format(), + }, ]; }); @@ -57,11 +74,13 @@ module('Acceptance | task fs path', function(hooks) { assert.ok(Path.entries[0].isDirectory); assert.equal(Path.entries[0].size, '3 MiB'); assert.equal(Path.entries[0].fileMode, 'drwxr-xr-x'); + assert.equal(Path.entries[0].lastModified, 'a year ago'); assert.equal(Path.entries[1].name, 'jorts'); assert.ok(Path.entries[1].isFile); assert.equal(Path.entries[1].size, '1 KiB'); assert.equal(Path.entries[1].fileMode, '-rw-r--r--'); + assert.equal(Path.entries[1].lastModified, '2 days ago'); assert.equal(Path.entries[2].name, 'jants'); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index df7cd29145f..b494bb0bad9 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -12,5 +12,6 @@ export default create({ size: text('[data-test-size]'), fileMode: text('[data-test-file-mode]'), + lastModified: text('[data-test-last-modified]'), }), }); From 976cff0cce5dbd3e692d60ea7cf641aab6d52221 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 10:55:05 -0500 Subject: [PATCH 015/101] Remove size from directory entries --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 2 +- ui/tests/acceptance/task-fs-path-test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 73b50e16be3..71cee647b5b 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -18,7 +18,7 @@ {{inline-svg 'folder-outline' class='icon'}} {{entry.Name}} - {{format-bytes entry.Size}} + {{entry.FileMode}} {{moment-from-now entry.ModTime}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 7cf7fa29617..fe6e4fb677e 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -72,7 +72,7 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); assert.ok(Path.entries[0].isDirectory); - assert.equal(Path.entries[0].size, '3 MiB'); + assert.equal(Path.entries[0].size, '', 'directory size are hidden'); assert.equal(Path.entries[0].fileMode, 'drwxr-xr-x'); assert.equal(Path.entries[0].lastModified, 'a year ago'); From 8eefd438f4e61805947df90227b75da13c4896f8 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 10:57:15 -0500 Subject: [PATCH 016/101] Remove file icon --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 71cee647b5b..35429a0769f 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -26,7 +26,7 @@ {{#each files as |entry|}} - {{inline-svg 'file-outline' class='icon'}} + {{entry.Name}} {{format-bytes entry.Size}} From f1a472988ee4d1824d947c0ef02a883e14bdf085 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 11:28:53 -0500 Subject: [PATCH 017/101] Add navigation into directories This will surely break under some circumstances; refinement to come. --- .../allocations/allocation/task/fs/path.js | 4 +- .../allocations/allocation/task/fs/path.hbs | 6 +- ui/tests/acceptance/task-fs-path-test.js | 57 ++++++++++++------- ui/tests/pages/allocations/task/fs/path.js | 4 +- 4 files changed, 44 insertions(+), 27 deletions(-) diff --git a/ui/app/routes/allocations/allocation/task/fs/path.js b/ui/app/routes/allocations/allocation/task/fs/path.js index ff301f35ea5..d0d73c77249 100644 --- a/ui/app/routes/allocations/allocation/task/fs/path.js +++ b/ui/app/routes/allocations/allocation/task/fs/path.js @@ -12,8 +12,8 @@ export default Route.extend({ return RSVP.hash({ path: decodedPath, task, - ls: fetch(`/v1/client/fs/ls/${allocation.id}?path=${task.name}`).then(response => - response.json() + ls: fetch(`/v1/client/fs/ls/${allocation.id}?path=${task.name}%2F${decodedPath}`).then( + response => response.json() ), }); }, diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 35429a0769f..4928fa6d26f 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -15,8 +15,10 @@ {{#each directories as |entry|}} - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} + {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat "%2F" entry.Name) activeClass="is-active"}} + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} + {{/link-to}} {{entry.FileMode}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index fe6e4fb677e..bb7c75cf7b4 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -42,28 +42,37 @@ module('Acceptance | task fs path', function(hooks) { }); test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { - this.server.get('/client/fs/ls/:allocation_id', () => { - return [ - { - Name: 'jorts', - IsDir: false, - Size: 1919, - FileMode: '-rw-r--r--', - ModTime: moment() - .subtract(2, 'day') - .format(), - }, - { Name: 'jants', IsDir: false }, - { - Name: 'directory', - IsDir: true, - Size: 3682561, - FileMode: 'drwxr-xr-x', - ModTime: moment() - .subtract(1, 'year') - .format(), - }, - ]; + this.server.get('/client/fs/ls/:allocation_id', (schema, { queryParams }) => { + if (queryParams.path.endsWith('directory')) { + return [ + { + Name: 'something', + IsDir: false, + }, + ]; + } else { + return [ + { + Name: 'jorts', + IsDir: false, + Size: 1919, + FileMode: '-rw-r--r--', + ModTime: moment() + .subtract(2, 'day') + .format(), + }, + { Name: 'jants', IsDir: false }, + { + Name: 'directory', + IsDir: true, + Size: 3682561, + FileMode: 'drwxr-xr-x', + ModTime: moment() + .subtract(1, 'year') + .format(), + }, + ]; + } }); await Path.visit({ id: allocation.id, name: task.name, path: 'somewhere' }); @@ -83,5 +92,9 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[1].lastModified, '2 days ago'); assert.equal(Path.entries[2].name, 'jants'); + + await Path.entries[0].visit(); + + assert.equal(Path.entries.length, 1); }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index b494bb0bad9..c5ac70f2530 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -1,4 +1,4 @@ -import { collection, create, isPresent, text, visitable } from 'ember-cli-page-object'; +import { clickable, collection, create, isPresent, text, visitable } from 'ember-cli-page-object'; export default create({ visit: visitable('/allocations/:id/:name/fs/:path'), @@ -13,5 +13,7 @@ export default create({ size: text('[data-test-size]'), fileMode: text('[data-test-file-mode]'), lastModified: text('[data-test-last-modified]'), + + visit: clickable('a'), }), }); From 65635bc93428d3d1f5d6834a10b212fefb93af3f Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 11:36:20 -0500 Subject: [PATCH 018/101] Move directory endpoint into general Mirage config --- ui/mirage/config.js | 40 +++++++++++++++++++----- ui/tests/acceptance/task-fs-path-test.js | 34 -------------------- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 35e55bca922..4820c81789b 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -5,6 +5,7 @@ import { logFrames, logEncode } from './data/logs'; import { generateDiff } from './factories/job-version'; import { generateTaskGroupFailures } from './factories/evaluation'; import { copy } from 'ember-copy'; +import moment from 'moment'; export function findLeader(schema) { const agent = schema.agents.first(); @@ -312,13 +313,38 @@ export default function() { this.get('/client/allocation/:id/stats', clientAllocationStatsHandler); this.get('/client/fs/logs/:allocation_id', clientAllocationLog); - // FIXME replace with more ORMy mocks? Nesting? Confine to tests only? 🧐 - this.get('/client/fs/ls/:allocation_id', () => { - return [ - { Name: 'jorts', IsDir: false, Size: 1919, FileMode: '-rw-r--r--' }, - { Name: 'jants', IsDir: false }, - { Name: 'directory', IsDir: true, Size: 3682561, FileMode: 'drwxr-xr-x' }, - ]; + // FIXME replace with more ORMy mocks? Confine to tests only? 🧐 + this.get('/client/fs/ls/:allocation_id', (schema, { queryParams }) => { + if (queryParams.path.endsWith('directory')) { + return [ + { + Name: 'something', + IsDir: false, + }, + ]; + } else { + return [ + { + Name: 'jorts', + IsDir: false, + Size: 1919, + FileMode: '-rw-r--r--', + ModTime: moment() + .subtract(2, 'day') + .format(), + }, + { Name: 'jants', IsDir: false }, + { + Name: 'directory', + IsDir: true, + Size: 3682561, + FileMode: 'drwxr-xr-x', + ModTime: moment() + .subtract(1, 'year') + .format(), + }, + ]; + } }); this.get('/client/stats', function({ clientStats }, { queryParams }) { diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index bb7c75cf7b4..ab97c09d4da 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -4,7 +4,6 @@ import { module, skip } from 'qunit'; import { setupApplicationTest, test } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import Path from 'nomad-ui/tests/pages/allocations/task/fs/path'; -import moment from 'moment'; let allocation; let task; @@ -42,39 +41,6 @@ module('Acceptance | task fs path', function(hooks) { }); test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { - this.server.get('/client/fs/ls/:allocation_id', (schema, { queryParams }) => { - if (queryParams.path.endsWith('directory')) { - return [ - { - Name: 'something', - IsDir: false, - }, - ]; - } else { - return [ - { - Name: 'jorts', - IsDir: false, - Size: 1919, - FileMode: '-rw-r--r--', - ModTime: moment() - .subtract(2, 'day') - .format(), - }, - { Name: 'jants', IsDir: false }, - { - Name: 'directory', - IsDir: true, - Size: 3682561, - FileMode: 'drwxr-xr-x', - ModTime: moment() - .subtract(1, 'year') - .format(), - }, - ]; - } - }); - await Path.visit({ id: allocation.id, name: task.name, path: 'somewhere' }); assert.equal(Path.entries.length, 3); From 0856bb0ef7bfc47e1af16d804313981ab2103bc3 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 12:06:57 -0500 Subject: [PATCH 019/101] Add preliminary styling --- ui/app/styles/components.scss | 1 + ui/app/styles/components/allocation-fs.scss | 12 ++++++++++++ .../allocations/allocation/task/fs/path.hbs | 4 ++-- 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 ui/app/styles/components/allocation-fs.scss diff --git a/ui/app/styles/components.scss b/ui/app/styles/components.scss index 031f1b886ab..b77a290b75f 100644 --- a/ui/app/styles/components.scss +++ b/ui/app/styles/components.scss @@ -1,4 +1,5 @@ @import './components/accordion'; +@import './components/allocation-fs'; @import './components/badge'; @import './components/boxed-section'; @import './components/codemirror'; diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss new file mode 100644 index 00000000000..fc3490547f8 --- /dev/null +++ b/ui/app/styles/components/allocation-fs.scss @@ -0,0 +1,12 @@ +.fs-explorer { + a { + text-decoration: none; + color: inherit; + + &:hover { + .name { + text-decoration: underline; + } + } + } +} diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 4928fa6d26f..b7b9943d406 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -2,7 +2,7 @@

      Path fs route {{path}}

      - +
      @@ -17,7 +17,7 @@ From df5b49ebad8450e334d2036f4c1ef48e5a4b37a9 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 12:15:30 -0500 Subject: [PATCH 020/101] Remove file mode column --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 3 --- ui/tests/acceptance/task-fs-path-test.js | 2 -- ui/tests/pages/allocations/task/fs/path.js | 1 - 3 files changed, 6 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index b7b9943d406..dc254c1868a 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -7,7 +7,6 @@ - @@ -21,7 +20,6 @@ {{/link-to}} - {{/each}} @@ -32,7 +30,6 @@ {{entry.Name}} - {{/each}} diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index ab97c09d4da..d34c53adb4b 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -48,13 +48,11 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); assert.ok(Path.entries[0].isDirectory); assert.equal(Path.entries[0].size, '', 'directory size are hidden'); - assert.equal(Path.entries[0].fileMode, 'drwxr-xr-x'); assert.equal(Path.entries[0].lastModified, 'a year ago'); assert.equal(Path.entries[1].name, 'jorts'); assert.ok(Path.entries[1].isFile); assert.equal(Path.entries[1].size, '1 KiB'); - assert.equal(Path.entries[1].fileMode, '-rw-r--r--'); assert.equal(Path.entries[1].lastModified, '2 days ago'); assert.equal(Path.entries[2].name, 'jants'); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index c5ac70f2530..4b573107178 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -11,7 +11,6 @@ export default create({ isDirectory: isPresent('[data-test-directory-icon]'), size: text('[data-test-size]'), - fileMode: text('[data-test-file-mode]'), lastModified: text('[data-test-last-modified]'), visit: clickable('a'), From acfed97bc8f699898b7e301378c13e8639f9c61d Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 13:01:06 -0500 Subject: [PATCH 021/101] Add preliminary explorer breadcrumbs --- .../allocations/allocation/task/fs/path.js | 5 +++++ ui/app/routes/allocations/allocation/task/fs/path.js | 11 +++++++---- .../templates/allocations/allocation/task/fs/path.hbs | 8 ++++++++ ui/tests/acceptance/task-fs-path-test.js | 10 ++++++++-- ui/tests/pages/allocations/task/fs/path.js | 2 ++ 5 files changed, 30 insertions(+), 6 deletions(-) diff --git a/ui/app/controllers/allocations/allocation/task/fs/path.js b/ui/app/controllers/allocations/allocation/task/fs/path.js index 851ee034ef1..4e5be5b66a1 100644 --- a/ui/app/controllers/allocations/allocation/task/fs/path.js +++ b/ui/app/controllers/allocations/allocation/task/fs/path.js @@ -1,7 +1,12 @@ import Controller from '@ember/controller'; +import { computed } from '@ember/object'; import { filterBy } from '@ember/object/computed'; export default Controller.extend({ directories: filterBy('ls', 'IsDir'), files: filterBy('ls', 'IsDir', false), + + pathComponents: computed('pathWithTaskName', function() { + return this.pathWithTaskName.split('/').reject(s => s === ''); + }), }); diff --git a/ui/app/routes/allocations/allocation/task/fs/path.js b/ui/app/routes/allocations/allocation/task/fs/path.js index d0d73c77249..b25e9681291 100644 --- a/ui/app/routes/allocations/allocation/task/fs/path.js +++ b/ui/app/routes/allocations/allocation/task/fs/path.js @@ -7,19 +7,22 @@ export default Route.extend({ const decodedPath = decodeURIComponent(path); const task = this.modelFor('allocations.allocation.task'); + const pathWithTaskName = `${task.name}${decodedPath}`; + const allocation = this.modelFor('allocations.allocation'); return RSVP.hash({ path: decodedPath, + pathWithTaskName, task, - ls: fetch(`/v1/client/fs/ls/${allocation.id}?path=${task.name}%2F${decodedPath}`).then( - response => response.json() + ls: fetch(`/v1/client/fs/ls/${allocation.id}?path=${pathWithTaskName}`).then(response => + response.json() ), }); }, - setupController(controller, { path, task, ls }) { + setupController(controller, { path, pathWithTaskName, task, ls }) { this._super(...arguments); - controller.setProperties({ path, model: task, ls }); + controller.setProperties({ path, pathWithTaskName, model: task, ls }); }, }); diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index dc254c1868a..d9534aa0202 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -2,6 +2,14 @@

      Path fs route {{path}}

      + +
      Name {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat "%2F" entry.Name) activeClass="is-active"}} {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} + {{entry.Name}} {{/link-to}}
      Name SizeMode Last Modified
      {{entry.FileMode}} {{moment-from-now entry.ModTime}}
      {{format-bytes entry.Size}}{{entry.FileMode}} {{moment-from-now entry.ModTime}}
      diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index d34c53adb4b..26c3762c831 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -40,11 +40,14 @@ module('Acceptance | task fs path', function(hooks) { }, Promise.resolve()); }); - test('visiting /allocations/:allocation_id/:task_name/fs/somewhere', async function(assert) { - await Path.visit({ id: allocation.id, name: task.name, path: 'somewhere' }); + test('visiting /allocations/:allocation_id/:task_name/fs/%2F', async function(assert) { + await Path.visit({ id: allocation.id, name: task.name, path: '/' }); assert.equal(Path.entries.length, 3); + assert.equal(Path.breadcrumbs.length, 1); + assert.equal(Path.breadcrumbs[0].text, task.name); + assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); assert.ok(Path.entries[0].isDirectory); assert.equal(Path.entries[0].size, '', 'directory size are hidden'); @@ -60,5 +63,8 @@ module('Acceptance | task fs path', function(hooks) { await Path.entries[0].visit(); assert.equal(Path.entries.length, 1); + + assert.equal(Path.breadcrumbs.length, 2); + assert.equal(Path.breadcrumbs[1].text, 'directory'); }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index 4b573107178..589019b0a00 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -5,6 +5,8 @@ export default create({ tempTitle: text('h1.title'), + breadcrumbs: collection('[data-test-fs-breadcrumbs] li'), + entries: collection('[data-test-entry]', { name: text('[data-test-name]'), isFile: isPresent('[data-test-file-icon]'), From 4dae8299f094c44b5a63382e9ce9fe057ca1f8d0 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 14:16:10 -0500 Subject: [PATCH 022/101] Add links to breadcrumb entries --- .../allocations/allocation/task/fs/path.js | 20 ++++++++++++++++++- ui/app/styles/components/allocation-fs.scss | 6 ++++++ .../allocations/allocation/task/fs/path.hbs | 10 +++++++--- ui/mirage/config.js | 7 +++++++ ui/tests/acceptance/task-fs-path-test.js | 10 ++++++++++ ui/tests/pages/allocations/task/fs/path.js | 4 +++- 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/ui/app/controllers/allocations/allocation/task/fs/path.js b/ui/app/controllers/allocations/allocation/task/fs/path.js index 4e5be5b66a1..22c31364a05 100644 --- a/ui/app/controllers/allocations/allocation/task/fs/path.js +++ b/ui/app/controllers/allocations/allocation/task/fs/path.js @@ -7,6 +7,24 @@ export default Controller.extend({ files: filterBy('ls', 'IsDir', false), pathComponents: computed('pathWithTaskName', function() { - return this.pathWithTaskName.split('/').reject(s => s === ''); + return this.pathWithTaskName + .split('/') + .reject(s => s === '') + .reduce( + (componentsAndPath, component) => { + componentsAndPath.components.push({ + name: component, + path: componentsAndPath.path, + }); + + componentsAndPath.path = `${componentsAndPath.path}/${component}`; + + return componentsAndPath; + }, + { + components: [], + path: '/', + } + ).components; }), }); diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss index fc3490547f8..a5eeac3be0d 100644 --- a/ui/app/styles/components/allocation-fs.scss +++ b/ui/app/styles/components/allocation-fs.scss @@ -10,3 +10,9 @@ } } } + +.breadcrumb.fs { + a { + color: inherit; + } +} diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index d9534aa0202..d1d7a2bcb4c 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -2,10 +2,14 @@

      Path fs route {{path}}

      -
      + + {{#each directories as |entry|}} + + + + + + {{/each}} + {{#each files as |entry|}} + + + + + + {{/each}} + +
      - {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat "%2F" entry.Name) activeClass="is-active"}} + {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} {{inline-svg 'folder-outline' class='icon'}} {{entry.Name}} {{/link-to}} diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 4820c81789b..58ba9dfaca9 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -316,6 +316,13 @@ export default function() { // FIXME replace with more ORMy mocks? Confine to tests only? 🧐 this.get('/client/fs/ls/:allocation_id', (schema, { queryParams }) => { if (queryParams.path.endsWith('directory')) { + return [ + { + Name: 'another', + IsDir: true, + }, + ]; + } else if (queryParams.path.endsWith('another')) { return [ { Name: 'something', diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 26c3762c831..c7911a9197f 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -66,5 +66,15 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.breadcrumbs.length, 2); assert.equal(Path.breadcrumbs[1].text, 'directory'); + + await Path.entries[0].visit(); + + assert.equal(Path.entries.length, 1); + + assert.equal(Path.breadcrumbs.length, 3); + assert.equal(Path.breadcrumbs[2].text, 'another'); + + await Path.breadcrumbs[1].visit(); + assert.equal(Path.breadcrumbs.length, 2); }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index 589019b0a00..9e7aab99238 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -5,7 +5,9 @@ export default create({ tempTitle: text('h1.title'), - breadcrumbs: collection('[data-test-fs-breadcrumbs] li'), + breadcrumbs: collection('[data-test-fs-breadcrumbs] li', { + visit: clickable('a'), + }), entries: collection('[data-test-entry]', { name: text('[data-test-name]'), From 2a41ca6cd299eabe32cef79edc001be7ca69248e Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 14:37:48 -0500 Subject: [PATCH 023/101] Add active styling to final breadcrumb --- .../allocations/allocation/task/fs/path.js | 3 ++- ui/app/styles/components/allocation-fs.scss | 4 ++++ .../templates/allocations/allocation/task/fs/path.hbs | 2 +- ui/tests/acceptance/task-fs-path-test.js | 5 +++++ ui/tests/pages/allocations/task/fs/path.js | 11 ++++++++++- 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/ui/app/controllers/allocations/allocation/task/fs/path.js b/ui/app/controllers/allocations/allocation/task/fs/path.js index 22c31364a05..320608ac5e9 100644 --- a/ui/app/controllers/allocations/allocation/task/fs/path.js +++ b/ui/app/controllers/allocations/allocation/task/fs/path.js @@ -11,10 +11,11 @@ export default Controller.extend({ .split('/') .reject(s => s === '') .reduce( - (componentsAndPath, component) => { + (componentsAndPath, component, componentIndex, components) => { componentsAndPath.components.push({ name: component, path: componentsAndPath.path, + isLast: componentIndex === components.length - 1, }); componentsAndPath.path = `${componentsAndPath.path}/${component}`; diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss index a5eeac3be0d..8b7183ee48c 100644 --- a/ui/app/styles/components/allocation-fs.scss +++ b/ui/app/styles/components/allocation-fs.scss @@ -15,4 +15,8 @@ a { color: inherit; } + + .is-active a { + color: inherit; + } } diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index d1d7a2bcb4c..9443f53dd57 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -5,7 +5,7 @@ - - - - - - - - - - {{#each directories as |entry|}} - - - - + {{#if isFile}} +
      placeholder file viewer
      + {{else}} +
      NameSizeLast Modified
      - {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} - {{/link-to}} - {{moment-from-now entry.ModTime}}
      + + + + + - {{/each}} - {{#each files as |entry|}} - - - - - - {{/each}} - -
      NameSizeLast Modified
      - - {{entry.Name}} - {{format-bytes entry.Size}}{{moment-from-now entry.ModTime}}
      +
      + {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} + {{/link-to}} + {{moment-from-now entry.ModTime}}
      + {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} + + {{entry.Name}} + {{/link-to}} + {{format-bytes entry.Size}}{{moment-from-now entry.ModTime}}
      + {{/if}}
      \ No newline at end of file diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 58ba9dfaca9..f0c23b4fb06 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -354,6 +354,12 @@ export default function() { } }); + this.get('/client/fs/stat/:allocation_id', () => { + return { + IsDir: true, + }; + }); + this.get('/client/stats', function({ clientStats }, { queryParams }) { const seed = Math.random(); if (seed > 0.8) { diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 37a71c48d8d..9a3910ae4fa 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -43,6 +43,8 @@ module('Acceptance | task fs path', function(hooks) { test('exploring allocation filesystem', async function(assert) { await Path.visit({ id: allocation.id, name: task.name, path: '/' }); + assert.ok(Path.fileViewer.isHidden); + assert.equal(Path.entries.length, 3); assert.equal(Path.breadcrumbsText, task.name); @@ -87,4 +89,17 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.breadcrumbsText, `${task.name} directory`); assert.equal(Path.breadcrumbs.length, 2); }); + + test('viewing a file', async function(assert) { + this.server.get('/client/fs/stat/:allocation_id', (schema, { queryParams }) => { + return { + IsDir: !queryParams.path.endsWith('jorts'), + }; + }); + + await Path.visit({ id: allocation.id, name: task.name, path: '/' }); + await Path.entries[1].visit(); + + assert.ok(Path.fileViewer.isPresent); + }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index f58614e379d..bc39f8f8360 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -13,6 +13,10 @@ export default create({ tempTitle: text('h1.title'), + fileViewer: { + scope: '[data-test-file-viewer]', + }, + breadcrumbsText: text('[data-test-fs-breadcrumbs]'), breadcrumbs: collection('[data-test-fs-breadcrumbs] li', { From 999f57ad2b737980ab7b8a4dec661dff254e95a2 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 15:57:52 -0500 Subject: [PATCH 029/101] Restore skipped test --- ui/tests/acceptance/task-fs-path-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 9a3910ae4fa..7402fd0e14e 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -1,6 +1,6 @@ import { currentURL } from '@ember/test-helpers'; import { Promise } from 'rsvp'; -import { module, skip } from 'qunit'; +import { module } from 'qunit'; import { setupApplicationTest, test } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; import Path from 'nomad-ui/tests/pages/allocations/task/fs/path'; @@ -21,7 +21,7 @@ module('Acceptance | task fs path', function(hooks) { task = server.schema.taskStates.where({ allocationId: allocation.id }).models[0]; }); - skip('visiting /allocations/:allocation_id/:task_name/fs/:path', async function(assert) { + test('visiting /allocations/:allocation_id/:task_name/fs/:path', async function(assert) { const paths = ['some-file.log', 'a/deep/path/to/a/file.log', '/', 'Unicode™®']; const testPath = async filePath => { From 02867c0b0c97bb257e75ee705680bdd2550ef367 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 16:10:34 -0500 Subject: [PATCH 030/101] Change test name --- ui/tests/acceptance/task-fs-path-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 7402fd0e14e..314fc61a904 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -40,7 +40,7 @@ module('Acceptance | task fs path', function(hooks) { }, Promise.resolve()); }); - test('exploring allocation filesystem', async function(assert) { + test('navigating allocation filesystem', async function(assert) { await Path.visit({ id: allocation.id, name: task.name, path: '/' }); assert.ok(Path.fileViewer.isHidden); From 7a15b2345eececab3bd96b101f3af84640d87596 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 16:14:00 -0500 Subject: [PATCH 031/101] Add extensions to files in mock structure This lets the mock endpoint be more general. --- ui/mirage/config.js | 8 ++++---- ui/tests/acceptance/task-fs-path-test.js | 10 ++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index f0c23b4fb06..3997a81a88a 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -332,7 +332,7 @@ export default function() { } else { return [ { - Name: 'jorts', + Name: 'jorts.txt', IsDir: false, Size: 1919, FileMode: '-rw-r--r--', @@ -340,7 +340,7 @@ export default function() { .subtract(2, 'day') .format(), }, - { Name: 'jants', IsDir: false }, + { Name: 'jants.txt', IsDir: false }, { Name: 'directory', IsDir: true, @@ -354,9 +354,9 @@ export default function() { } }); - this.get('/client/fs/stat/:allocation_id', () => { + this.get('/client/fs/stat/:allocation_id', (schema, { queryParams }) => { return { - IsDir: true, + IsDir: !queryParams.path.endsWith('.txt'), }; }); diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 314fc61a904..27c77ddbcf8 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -58,12 +58,12 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[0].size, '', 'directory sizes are hidden'); assert.equal(Path.entries[0].lastModified, 'a year ago'); - assert.equal(Path.entries[1].name, 'jorts'); + assert.equal(Path.entries[1].name, 'jorts.txt'); assert.ok(Path.entries[1].isFile); assert.equal(Path.entries[1].size, '1 KiB'); assert.equal(Path.entries[1].lastModified, '2 days ago'); - assert.equal(Path.entries[2].name, 'jants'); + assert.equal(Path.entries[2].name, 'jants.txt'); await Path.entries[0].visit(); @@ -91,12 +91,6 @@ module('Acceptance | task fs path', function(hooks) { }); test('viewing a file', async function(assert) { - this.server.get('/client/fs/stat/:allocation_id', (schema, { queryParams }) => { - return { - IsDir: !queryParams.path.endsWith('jorts'), - }; - }); - await Path.visit({ id: allocation.id, name: task.name, path: '/' }); await Path.entries[1].visit(); From c59282e4c2ea6dd01b9022bd7aca62b0a1c3fc05 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 16:23:12 -0500 Subject: [PATCH 032/101] Change example filenames to contain emoji --- ui/mirage/config.js | 4 ++-- ui/tests/acceptance/task-fs-path-test.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 3997a81a88a..e739f09147d 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -332,7 +332,7 @@ export default function() { } else { return [ { - Name: 'jorts.txt', + Name: '🤩.txt', IsDir: false, Size: 1919, FileMode: '-rw-r--r--', @@ -340,7 +340,7 @@ export default function() { .subtract(2, 'day') .format(), }, - { Name: 'jants.txt', IsDir: false }, + { Name: '🙌🏿.txt', IsDir: false }, { Name: 'directory', IsDir: true, diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 27c77ddbcf8..ca1bc71c442 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -58,12 +58,12 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.entries[0].size, '', 'directory sizes are hidden'); assert.equal(Path.entries[0].lastModified, 'a year ago'); - assert.equal(Path.entries[1].name, 'jorts.txt'); + assert.equal(Path.entries[1].name, '🤩.txt'); assert.ok(Path.entries[1].isFile); assert.equal(Path.entries[1].size, '1 KiB'); assert.equal(Path.entries[1].lastModified, '2 days ago'); - assert.equal(Path.entries[2].name, 'jants.txt'); + assert.equal(Path.entries[2].name, '🙌🏿.txt'); await Path.entries[0].visit(); From e77f2ebb213e5f4540c0a9ad0956efc22ecfd851 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 16:24:04 -0500 Subject: [PATCH 033/101] Add assertion about final filename breadcrumb --- ui/tests/acceptance/task-fs-path-test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index ca1bc71c442..74746736302 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -94,6 +94,8 @@ module('Acceptance | task fs path', function(hooks) { await Path.visit({ id: allocation.id, name: task.name, path: '/' }); await Path.entries[1].visit(); + assert.equal(Path.breadcrumbsText, `${task.name} 🤩.txt`); + assert.ok(Path.fileViewer.isPresent); }); }); From 53213a037374e1e50e7879e7cdb2efb2bb487039 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Mon, 24 Jun 2019 16:32:27 -0500 Subject: [PATCH 034/101] Add extension to nested file --- ui/mirage/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index e739f09147d..d1287717cba 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -325,7 +325,7 @@ export default function() { } else if (queryParams.path.endsWith('another')) { return [ { - Name: 'something', + Name: 'something.txt', IsDir: false, }, ]; From 912f7303be4e94cd6af37ed0e67e0d015fc11c61 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 09:29:19 -0500 Subject: [PATCH 035/101] Rename page object property --- ui/tests/acceptance/task-fs-path-test.js | 30 +++++++++++----------- ui/tests/pages/allocations/task/fs/path.js | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 74746736302..4c51ba5e3b3 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -45,7 +45,7 @@ module('Acceptance | task fs path', function(hooks) { assert.ok(Path.fileViewer.isHidden); - assert.equal(Path.entries.length, 3); + assert.equal(Path.directoryEntries.length, 3); assert.equal(Path.breadcrumbsText, task.name); @@ -53,21 +53,21 @@ module('Acceptance | task fs path', function(hooks) { assert.ok(Path.breadcrumbs[0].isActive); assert.equal(Path.breadcrumbs[0].text, task.name); - assert.equal(Path.entries[0].name, 'directory', 'directories should come first'); - assert.ok(Path.entries[0].isDirectory); - assert.equal(Path.entries[0].size, '', 'directory sizes are hidden'); - assert.equal(Path.entries[0].lastModified, 'a year ago'); + assert.equal(Path.directoryEntries[0].name, 'directory', 'directories should come first'); + assert.ok(Path.directoryEntries[0].isDirectory); + assert.equal(Path.directoryEntries[0].size, '', 'directory sizes are hidden'); + assert.equal(Path.directoryEntries[0].lastModified, 'a year ago'); - assert.equal(Path.entries[1].name, '🤩.txt'); - assert.ok(Path.entries[1].isFile); - assert.equal(Path.entries[1].size, '1 KiB'); - assert.equal(Path.entries[1].lastModified, '2 days ago'); + assert.equal(Path.directoryEntries[1].name, '🤩.txt'); + assert.ok(Path.directoryEntries[1].isFile); + assert.equal(Path.directoryEntries[1].size, '1 KiB'); + assert.equal(Path.directoryEntries[1].lastModified, '2 days ago'); - assert.equal(Path.entries[2].name, '🙌🏿.txt'); + assert.equal(Path.directoryEntries[2].name, '🙌🏿.txt'); - await Path.entries[0].visit(); + await Path.directoryEntries[0].visit(); - assert.equal(Path.entries.length, 1); + assert.equal(Path.directoryEntries.length, 1); assert.equal(Path.breadcrumbs.length, 2); assert.equal(Path.breadcrumbsText, `${task.name} directory`); @@ -77,9 +77,9 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.breadcrumbs[1].text, 'directory'); assert.ok(Path.breadcrumbs[1].isActive); - await Path.entries[0].visit(); + await Path.directoryEntries[0].visit(); - assert.equal(Path.entries.length, 1); + assert.equal(Path.directoryEntries.length, 1); assert.equal(Path.breadcrumbs.length, 3); assert.equal(Path.breadcrumbsText, `${task.name} directory another`); @@ -92,7 +92,7 @@ module('Acceptance | task fs path', function(hooks) { test('viewing a file', async function(assert) { await Path.visit({ id: allocation.id, name: task.name, path: '/' }); - await Path.entries[1].visit(); + await Path.directoryEntries[1].visit(); assert.equal(Path.breadcrumbsText, `${task.name} 🤩.txt`); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index bc39f8f8360..3c17a2890de 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -24,7 +24,7 @@ export default create({ isActive: hasClass('is-active'), }), - entries: collection('[data-test-entry]', { + directoryEntries: collection('[data-test-entry]', { name: text('[data-test-name]'), isFile: isPresent('[data-test-file-icon]'), isDirectory: isPresent('[data-test-directory-icon]'), From 6ca3b5ad2861327567cbade91707dba054591352 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 09:45:10 -0500 Subject: [PATCH 036/101] Add check for leading slash in path --- ui/app/routes/allocations/allocation/task/fs/path.js | 2 +- ui/tests/acceptance/task-fs-path-test.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/app/routes/allocations/allocation/task/fs/path.js b/ui/app/routes/allocations/allocation/task/fs/path.js index ea3e9e62429..f0fe0295f0f 100644 --- a/ui/app/routes/allocations/allocation/task/fs/path.js +++ b/ui/app/routes/allocations/allocation/task/fs/path.js @@ -7,7 +7,7 @@ export default Route.extend({ const decodedPath = decodeURIComponent(path); const task = this.modelFor('allocations.allocation.task'); - const pathWithTaskName = `${task.name}${decodedPath}`; + const pathWithTaskName = `${task.name}${decodedPath.startsWith('/') ? '' : '/'}${decodedPath}`; const allocation = this.modelFor('allocations.allocation'); diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index 4c51ba5e3b3..3142083847f 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -31,6 +31,7 @@ module('Acceptance | task fs path', function(hooks) { `/allocations/${allocation.id}/${task.name}/fs/${encodeURIComponent(filePath)}`, 'No redirect' ); + assert.equal(Path.breadcrumbsText, `${task.name} ${filePath.replace(/\//g, ' ')}`.trim()); assert.ok(Path.tempTitle.includes(filePath), `Temp title includes path, ${filePath}`); }; From 806b9bfb341411976601d3a8c5475149c4c86152 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 09:46:04 -0500 Subject: [PATCH 037/101] Remove temporary title --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 2 -- ui/tests/acceptance/task-fs-path-test.js | 1 - ui/tests/pages/allocations/task/fs/path.js | 2 -- 3 files changed, 5 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index ad192408e08..dbb4ecd74e0 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -1,7 +1,5 @@ {{partial "allocations/allocation/task/subnav"}}
      -

      Path fs route {{path}}

      -
      \ No newline at end of file From 3d0f4e23b6a81117621243269b83dd0da6444aa9 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 10:26:00 -0500 Subject: [PATCH 042/101] Updating styling of breadcrumbs --- ui/app/styles/components/allocation-fs.scss | 29 +++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss index 514ad4db272..4df497b88ab 100644 --- a/ui/app/styles/components/allocation-fs.scss +++ b/ui/app/styles/components/allocation-fs.scss @@ -1,24 +1,37 @@ .fs-explorer.table { width: 100%; - a { - text-decoration: none; - color: inherit; + tbody { + a { + text-decoration: none; + color: inherit; - &:hover { - .name { - text-decoration: underline; + &:hover { + .name { + text-decoration: underline; + } } } } } .breadcrumb.fs { + margin: 0; + a { - color: inherit; + padding-top: 0; + padding-bottom: 0; + color: $blue; + opacity: 1; + font-weight: $weight-bold; + text-decoration: none; + + &:hover { + text-decoration: underline; + } } .is-active a { - color: inherit; + color: $black; } } From d12df393054074a4a6d237a5352e8f5ddf5211fe Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 11:19:44 -0500 Subject: [PATCH 043/101] Add missing class name --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 72729dfbff4..89ef1b9a94a 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -52,7 +52,7 @@ {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{entry.Name}} + {{entry.Name}} {{/link-to}} {{format-bytes entry.Size}} From 5593ae639791b07a7d0592bd9b90c8fbba6ffc27 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 12:04:01 -0500 Subject: [PATCH 044/101] Add auto-updating to modification times --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 89ef1b9a94a..7cc9e084529 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -44,7 +44,7 @@ {{/link-to}} - {{moment-from-now entry.ModTime}} + {{moment-from-now entry.ModTime interval=1000}} {{/each}} {{#each files as |entry|}} @@ -56,7 +56,7 @@ {{/link-to}} {{format-bytes entry.Size}} - {{moment-from-now entry.ModTime}} + {{moment-from-now entry.ModTime interval=1000}} {{/each}} From 0e8f5699cb4ca3835a8989faef745caeb4c4a56e Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 12:05:57 -0500 Subject: [PATCH 045/101] Change to use less-redundant datetime formatter --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 7cc9e084529..3710510ec5b 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -44,7 +44,7 @@ {{/link-to}} - {{moment-from-now entry.ModTime interval=1000}} + {{moment-from entry.ModTime interval=1000}} {{/each}} {{#each files as |entry|}} @@ -56,7 +56,7 @@ {{/link-to}} {{format-bytes entry.Size}} - {{moment-from-now entry.ModTime interval=1000}} + {{moment-from entry.ModTime interval=1000}} {{/each}} From 343a0937b68f2f191d44cfe2bd7cb5bceda249c6 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 12:42:09 -0500 Subject: [PATCH 046/101] Add another example modification date --- ui/mirage/config.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index d1287717cba..65b5e4d04a8 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -340,7 +340,13 @@ export default function() { .subtract(2, 'day') .format(), }, - { Name: '🙌🏿.txt', IsDir: false }, + { + Name: '🙌🏿.txt', + IsDir: false, + ModTime: moment() + .subtract(2, 'minute') + .format(), + }, { Name: 'directory', IsDir: true, From 16fcf9c31565d3b6e601ffb2be3abeb9b82e5dda Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 16:19:02 -0500 Subject: [PATCH 047/101] Restore file icon --- ui/app/templates/allocations/allocation/task/fs/path.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 3710510ec5b..9890aebc0ca 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -51,7 +51,7 @@ {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - + {{inline-svg 'file-outline' class='icon'}} {{entry.Name}} {{/link-to}} From 8c28f576ce989995e2a46c101322f30b273d7e8a Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 19:16:50 -0500 Subject: [PATCH 048/101] Add handling for empty directories --- .../allocations/allocation/task/fs/path.hbs | 77 +++++++++++-------- ui/mirage/config.js | 8 +- ui/tests/acceptance/task-fs-path-test.js | 21 +++-- ui/tests/pages/allocations/task/fs/path.js | 2 + 4 files changed, 67 insertions(+), 41 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs index 9890aebc0ca..a333f8521d7 100644 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ b/ui/app/templates/allocations/allocation/task/fs/path.hbs @@ -27,39 +27,50 @@ {{else}} - - - Name - File Size - Last Modified - - - - {{#each directories as |entry|}} - - - {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} - {{/link-to}} - - - {{moment-from entry.ModTime interval=1000}} - - {{/each}} - {{#each files as |entry|}} - - - {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'file-outline' class='icon'}} - {{entry.Name}} - {{/link-to}} - - {{format-bytes entry.Size}} - {{moment-from entry.ModTime interval=1000}} - - {{/each}} - + {{#if ls}} + + + Name + File Size + Last Modified + + + + {{#each directories as |entry|}} + + + {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} + {{/link-to}} + + + {{moment-from entry.ModTime interval=1000}} + + {{/each}} + {{#each files as |entry|}} + + + {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} + {{inline-svg 'file-outline' class='icon'}} + {{entry.Name}} + {{/link-to}} + + {{format-bytes entry.Size}} + {{moment-from entry.ModTime interval=1000}} + + {{/each}} + + {{else}} + + + + {{inline-svg 'alert-circle-outline' class='icon'}} + Directory is empty + + + + {{/if}} {{/if}} \ No newline at end of file diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 65b5e4d04a8..51c86149e1f 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -315,7 +315,9 @@ export default function() { // FIXME replace with more ORMy mocks? Confine to tests only? 🧐 this.get('/client/fs/ls/:allocation_id', (schema, { queryParams }) => { - if (queryParams.path.endsWith('directory')) { + if (queryParams.path.endsWith('empty-directory')) { + return []; + } else if (queryParams.path.endsWith('directory')) { return [ { Name: 'another', @@ -356,6 +358,10 @@ export default function() { .subtract(1, 'year') .format(), }, + { + Name: 'empty-directory', + IsDir: true, + }, ]; } }); diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js index c702580da82..1fd6e21864e 100644 --- a/ui/tests/acceptance/task-fs-path-test.js +++ b/ui/tests/acceptance/task-fs-path-test.js @@ -45,7 +45,7 @@ module('Acceptance | task fs path', function(hooks) { assert.ok(Path.fileViewer.isHidden); - assert.equal(Path.directoryEntries.length, 3); + assert.equal(Path.directoryEntries.length, 4); assert.equal(Path.breadcrumbsText, task.name); @@ -58,12 +58,12 @@ module('Acceptance | task fs path', function(hooks) { assert.equal(Path.directoryEntries[0].size, '', 'directory sizes are hidden'); assert.equal(Path.directoryEntries[0].lastModified, 'a year ago'); - assert.equal(Path.directoryEntries[1].name, '🤩.txt'); - assert.ok(Path.directoryEntries[1].isFile); - assert.equal(Path.directoryEntries[1].size, '1 KiB'); - assert.equal(Path.directoryEntries[1].lastModified, '2 days ago'); + assert.equal(Path.directoryEntries[2].name, '🤩.txt'); + assert.ok(Path.directoryEntries[2].isFile); + assert.equal(Path.directoryEntries[2].size, '1 KiB'); + assert.equal(Path.directoryEntries[2].lastModified, '2 days ago'); - assert.equal(Path.directoryEntries[2].name, '🙌🏿.txt'); + assert.equal(Path.directoryEntries[3].name, '🙌🏿.txt'); await Path.directoryEntries[0].visit(); @@ -92,10 +92,17 @@ module('Acceptance | task fs path', function(hooks) { test('viewing a file', async function(assert) { await Path.visit({ id: allocation.id, name: task.name, path: '/' }); - await Path.directoryEntries[1].visit(); + await Path.directoryEntries[2].visit(); assert.equal(Path.breadcrumbsText, `${task.name} 🤩.txt`); assert.ok(Path.fileViewer.isPresent); }); + + test('viewing an empty directory', async function(assert) { + await Path.visit({ id: allocation.id, name: task.name, path: '/empty-directory' }); + + assert.equal(Path.directoryEntries.length, 1); + assert.ok(Path.directoryEntries[0].isEmpty); + }); }); diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js index 52d1826feb2..2e3411104cc 100644 --- a/ui/tests/pages/allocations/task/fs/path.js +++ b/ui/tests/pages/allocations/task/fs/path.js @@ -24,8 +24,10 @@ export default create({ directoryEntries: collection('[data-test-entry]', { name: text('[data-test-name]'), + isFile: isPresent('[data-test-file-icon]'), isDirectory: isPresent('[data-test-directory-icon]'), + isEmpty: isPresent('[data-test-empty-icon]'), size: text('[data-test-size]'), lastModified: text('[data-test-last-modified]'), From 3fafe6859b0920c1a124e98022ec3e28100e3121 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 25 Jun 2019 19:33:13 -0500 Subject: [PATCH 049/101] Update Mirage scenario to work reliably It would periodically display an error when visiting a deep link into the allocation filesystem. --- ui/mirage/scenarios/default.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ui/mirage/scenarios/default.js b/ui/mirage/scenarios/default.js index 89f656acb01..e8aa6a24268 100644 --- a/ui/mirage/scenarios/default.js +++ b/ui/mirage/scenarios/default.js @@ -134,7 +134,9 @@ function allocationFileExplorer(server) { jobId: job.id, }); server.create('task', { name: 'task', taskGroup: taskGroup }); - server.create('allocation', 'rescheduled', { + server.create('allocation', { + clientStatus: 'running', + desiredStatus: 'run', id: '12345', jobId: job.id, taskGroup: taskGroup.name, From df533466b40f94a9cb05dfb3a55c7d3362418edf Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 09:35:33 -0500 Subject: [PATCH 050/101] Add modification times to all example files --- ui/mirage/config.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index 51c86149e1f..54809bfc110 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -322,6 +322,7 @@ export default function() { { Name: 'another', IsDir: true, + ModTime: moment().format(), }, ]; } else if (queryParams.path.endsWith('another')) { @@ -329,6 +330,7 @@ export default function() { { Name: 'something.txt', IsDir: false, + ModTime: moment().format(), }, ]; } else { @@ -361,6 +363,7 @@ export default function() { { Name: 'empty-directory', IsDir: true, + ModTime: moment().format(), }, ]; } From 8fd85b56785896546a1b8c19c3af1c47c08533f2 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 14:29:39 -0500 Subject: [PATCH 051/101] =?UTF-8?q?Update=20routing=20so=20=E2=80=A6/fs=20?= =?UTF-8?q?shows=20root=20directory?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a bit strange but I couldn’t figure out another way apart from extracting to a component, and it seemed like a shame to lose the built-in functionality of routes. --- .../allocations/allocation/task/fs-root.js | 3 + .../allocation/task/{fs/path.js => fs.js} | 0 ui/app/router.js | 5 +- .../allocations/allocation/task/fs-root.js | 5 ++ .../allocation/task/{fs/path.js => fs.js} | 2 +- .../allocations/allocation/task/fs.hbs | 87 ++++++++++++++++++- .../allocations/allocation/task/fs/index.hbs | 14 --- .../allocations/allocation/task/fs/path.hbs | 76 ---------------- .../allocations/allocation/task/subnav.hbs | 3 +- 9 files changed, 98 insertions(+), 97 deletions(-) create mode 100644 ui/app/controllers/allocations/allocation/task/fs-root.js rename ui/app/controllers/allocations/allocation/task/{fs/path.js => fs.js} (100%) create mode 100644 ui/app/routes/allocations/allocation/task/fs-root.js rename ui/app/routes/allocations/allocation/task/{fs/path.js => fs.js} (98%) delete mode 100644 ui/app/templates/allocations/allocation/task/fs/index.hbs delete mode 100644 ui/app/templates/allocations/allocation/task/fs/path.hbs diff --git a/ui/app/controllers/allocations/allocation/task/fs-root.js b/ui/app/controllers/allocations/allocation/task/fs-root.js new file mode 100644 index 00000000000..2297a800ea1 --- /dev/null +++ b/ui/app/controllers/allocations/allocation/task/fs-root.js @@ -0,0 +1,3 @@ +import FSController from './fs'; + +export default FSController.extend(); diff --git a/ui/app/controllers/allocations/allocation/task/fs/path.js b/ui/app/controllers/allocations/allocation/task/fs.js similarity index 100% rename from ui/app/controllers/allocations/allocation/task/fs/path.js rename to ui/app/controllers/allocations/allocation/task/fs.js diff --git a/ui/app/router.js b/ui/app/router.js index c27cd4c2dcd..a8bfd1dd318 100644 --- a/ui/app/router.js +++ b/ui/app/router.js @@ -32,9 +32,8 @@ Router.map(function() { this.route('allocation', { path: '/:allocation_id' }, function() { this.route('task', { path: '/:name' }, function() { this.route('logs'); - this.route('fs', function() { - this.route('path', { path: '/*path' }); - }); + this.route('fs-root', { path: '/fs' }); + this.route('fs', { path: '/fs/*path' }); }); }); }); diff --git a/ui/app/routes/allocations/allocation/task/fs-root.js b/ui/app/routes/allocations/allocation/task/fs-root.js new file mode 100644 index 00000000000..83cd7d91649 --- /dev/null +++ b/ui/app/routes/allocations/allocation/task/fs-root.js @@ -0,0 +1,5 @@ +import PathRoute from './fs'; + +export default PathRoute.extend({ + templateName: 'allocations/allocation/task/fs', +}); diff --git a/ui/app/routes/allocations/allocation/task/fs/path.js b/ui/app/routes/allocations/allocation/task/fs.js similarity index 98% rename from ui/app/routes/allocations/allocation/task/fs/path.js rename to ui/app/routes/allocations/allocation/task/fs.js index f0fe0295f0f..191d140e32d 100644 --- a/ui/app/routes/allocations/allocation/task/fs/path.js +++ b/ui/app/routes/allocations/allocation/task/fs.js @@ -3,7 +3,7 @@ import fetch from 'nomad-ui/utils/fetch'; import RSVP from 'rsvp'; export default Route.extend({ - model({ path }) { + model({ path = '/' }) { const decodedPath = decodeURIComponent(path); const task = this.modelFor('allocations.allocation.task'); diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index e2147cab02d..00ed1549571 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -1 +1,86 @@ -{{outlet}} \ No newline at end of file +{{partial "allocations/allocation/task/subnav"}} +
      +

      Index fs route

      + {{#if model.isRunning}} + + + + + + + {{#if isFile}} + + + + + + {{else}} + {{#if ls}} + + + + + + + + + {{#each directories as |entry|}} + + + + + + {{/each}} + {{#each files as |entry|}} + + + + + + {{/each}} + + {{else}} + + + + + + {{/if}} + {{/if}} +
      + +
      +
      placeholder file viewer
      +
      NameFile SizeLast Modified
      + {{#link-to "allocations.allocation.task.fs" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} + {{inline-svg 'folder-outline' class='icon'}} + {{entry.Name}} + {{/link-to}} + {{moment-from entry.ModTime interval=1000}}
      + {{#link-to "allocations.allocation.task.fs" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} + {{inline-svg 'file-outline' class='icon'}} + {{entry.Name}} + {{/link-to}} + {{format-bytes entry.Size}}{{moment-from entry.ModTime interval=1000}}
      + {{inline-svg 'alert-circle-outline' class='icon'}} + Directory is empty +
      + {{else}} +
      +

      Task is not Running

      +

      + Cannot access files of a task that is not running. +

      +
      + {{/if}} +
      \ No newline at end of file diff --git a/ui/app/templates/allocations/allocation/task/fs/index.hbs b/ui/app/templates/allocations/allocation/task/fs/index.hbs deleted file mode 100644 index ba5a3401b5f..00000000000 --- a/ui/app/templates/allocations/allocation/task/fs/index.hbs +++ /dev/null @@ -1,14 +0,0 @@ -{{partial "allocations/allocation/task/subnav"}} -
      -

      Index fs route

      - {{#if model.isRunning}} - Task is running, show file explorer. - {{else}} -
      -

      Task is not Running

      -

      - Cannot access files of a task that is not running. -

      -
      - {{/if}} -
      \ No newline at end of file diff --git a/ui/app/templates/allocations/allocation/task/fs/path.hbs b/ui/app/templates/allocations/allocation/task/fs/path.hbs deleted file mode 100644 index a333f8521d7..00000000000 --- a/ui/app/templates/allocations/allocation/task/fs/path.hbs +++ /dev/null @@ -1,76 +0,0 @@ -{{partial "allocations/allocation/task/subnav"}} -
      - - - - - - - {{#if isFile}} - - - - - - {{else}} - {{#if ls}} - - - - - - - - - {{#each directories as |entry|}} - - - - - - {{/each}} - {{#each files as |entry|}} - - - - - - {{/each}} - - {{else}} - - - - - - {{/if}} - {{/if}} -
      - -
      -
      placeholder file viewer
      -
      NameFile SizeLast Modified
      - {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} - {{/link-to}} - {{moment-from entry.ModTime interval=1000}}
      - {{#link-to "allocations.allocation.task.fs.path" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'file-outline' class='icon'}} - {{entry.Name}} - {{/link-to}} - {{format-bytes entry.Size}}{{moment-from entry.ModTime interval=1000}}
      - {{inline-svg 'alert-circle-outline' class='icon'}} - Directory is empty -
      -
      \ No newline at end of file diff --git a/ui/app/templates/allocations/allocation/task/subnav.hbs b/ui/app/templates/allocations/allocation/task/subnav.hbs index 2716182c3c3..59c8d852a70 100644 --- a/ui/app/templates/allocations/allocation/task/subnav.hbs +++ b/ui/app/templates/allocations/allocation/task/subnav.hbs @@ -2,7 +2,6 @@
      • {{#link-to "allocations.allocation.task.index" model.allocation model activeClass="is-active"}}Overview{{/link-to}}
      • {{#link-to "allocations.allocation.task.logs" model.allocation model activeClass="is-active"}}Logs{{/link-to}}
      • - {{! FIXME remove hardcoded root path }} -
      • {{#link-to "allocations.allocation.task.fs.path" model.allocation model "%2F" activeClass="is-active"}}Files{{/link-to}}
      • +
      • {{#link-to "allocations.allocation.task.fs-root" model.allocation model activeClass="is-active"}}Files{{/link-to}}
      From c0d1cddf63c3f969e098a5be7f8efa9caa6aa8bd Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 14:37:39 -0500 Subject: [PATCH 052/101] Remove placeholder title --- ui/app/templates/allocations/allocation/task/fs.hbs | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 00ed1549571..949fd8b5aa2 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -1,6 +1,5 @@ {{partial "allocations/allocation/task/subnav"}}
      -

      Index fs route

      {{#if model.isRunning}} From 65ddf939f8c65b4ae6279c5044be651ad3ccc38b Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 14:50:09 -0500 Subject: [PATCH 053/101] Change fs retrieval to happen via token service --- ui/app/routes/allocations/allocation/task/fs.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ui/app/routes/allocations/allocation/task/fs.js b/ui/app/routes/allocations/allocation/task/fs.js index 191d140e32d..1c520ca4ccb 100644 --- a/ui/app/routes/allocations/allocation/task/fs.js +++ b/ui/app/routes/allocations/allocation/task/fs.js @@ -1,8 +1,10 @@ import Route from '@ember/routing/route'; -import fetch from 'nomad-ui/utils/fetch'; +import { inject as service } from '@ember/service'; import RSVP from 'rsvp'; export default Route.extend({ + token: service(), + model({ path = '/' }) { const decodedPath = decodeURIComponent(path); const task = this.modelFor('allocations.allocation.task'); @@ -11,7 +13,8 @@ export default Route.extend({ const allocation = this.modelFor('allocations.allocation'); - return fetch(`/v1/client/fs/stat/${allocation.id}?path=${pathWithTaskName}`) + return this.token + .authorizedRequest(`/v1/client/fs/stat/${allocation.id}?path=${pathWithTaskName}`) .then(response => response.json()) .then(statJson => { if (statJson.IsDir) { @@ -19,9 +22,9 @@ export default Route.extend({ path: decodedPath, pathWithTaskName, task, - ls: fetch(`/v1/client/fs/ls/${allocation.id}?path=${pathWithTaskName}`).then(response => - response.json() - ), + ls: this.token + .authorizedRequest(`/v1/client/fs/ls/${allocation.id}?path=${pathWithTaskName}`) + .then(response => response.json()), isFile: false, }); } else { From dab54a64bd37956d402561d4fb776a53939b0d51 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 15:16:06 -0500 Subject: [PATCH 054/101] Move fs API queries into adapter --- ui/app/adapters/task-state.js | 18 ++++++++ ui/app/models/task-state.js | 8 ++++ .../routes/allocations/allocation/task/fs.js | 46 ++++++++----------- 3 files changed, 44 insertions(+), 28 deletions(-) create mode 100644 ui/app/adapters/task-state.js diff --git a/ui/app/adapters/task-state.js b/ui/app/adapters/task-state.js new file mode 100644 index 00000000000..08aff1ed9b4 --- /dev/null +++ b/ui/app/adapters/task-state.js @@ -0,0 +1,18 @@ +import ApplicationAdapter from './application'; +import { inject as service } from '@ember/service'; + +export default ApplicationAdapter.extend({ + token: service(), + + ls(model, path) { + return this.token + .authorizedRequest(`/v1/client/fs/ls/${model.allocation.id}?path=${path}`) + .then(response => response.json()); + }, + + stat(model, path) { + return this.token + .authorizedRequest(`/v1/client/fs/stat/${model.allocation.id}?path=${path}`) + .then(response => response.json()); + }, +}); diff --git a/ui/app/models/task-state.js b/ui/app/models/task-state.js index 66ef8fbe303..754a68f61e2 100644 --- a/ui/app/models/task-state.js +++ b/ui/app/models/task-state.js @@ -47,4 +47,12 @@ export default Fragment.extend({ restart() { return this.allocation.restart(this.name); }, + + ls(path) { + return this.store.adapterFor('task-state').ls(this, path); + }, + + stat(path) { + return this.store.adapterFor('task-state').stat(this, path); + }, }); diff --git a/ui/app/routes/allocations/allocation/task/fs.js b/ui/app/routes/allocations/allocation/task/fs.js index 1c520ca4ccb..15cb5f872e2 100644 --- a/ui/app/routes/allocations/allocation/task/fs.js +++ b/ui/app/routes/allocations/allocation/task/fs.js @@ -1,41 +1,31 @@ import Route from '@ember/routing/route'; -import { inject as service } from '@ember/service'; import RSVP from 'rsvp'; export default Route.extend({ - token: service(), - model({ path = '/' }) { const decodedPath = decodeURIComponent(path); const task = this.modelFor('allocations.allocation.task'); const pathWithTaskName = `${task.name}${decodedPath.startsWith('/') ? '' : '/'}${decodedPath}`; - const allocation = this.modelFor('allocations.allocation'); - - return this.token - .authorizedRequest(`/v1/client/fs/stat/${allocation.id}?path=${pathWithTaskName}`) - .then(response => response.json()) - .then(statJson => { - if (statJson.IsDir) { - return RSVP.hash({ - path: decodedPath, - pathWithTaskName, - task, - ls: this.token - .authorizedRequest(`/v1/client/fs/ls/${allocation.id}?path=${pathWithTaskName}`) - .then(response => response.json()), - isFile: false, - }); - } else { - return { - path: decodedPath, - pathWithTaskName, - task, - isFile: true, - }; - } - }); + return task.stat(pathWithTaskName).then(statJson => { + if (statJson.IsDir) { + return RSVP.hash({ + path: decodedPath, + pathWithTaskName, + task, + ls: task.ls(pathWithTaskName), + isFile: false, + }); + } else { + return { + path: decodedPath, + pathWithTaskName, + task, + isFile: true, + }; + } + }); }, setupController(controller, { path, pathWithTaskName, task, ls, isFile }) { From 84a4b78a6d71fe625601b092c62c68e8a676fa69 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 15:22:52 -0500 Subject: [PATCH 055/101] Rename property for directory listing --- ui/app/controllers/allocations/allocation/task/fs.js | 4 ++-- ui/app/routes/allocations/allocation/task/fs.js | 6 +++--- ui/app/templates/allocations/allocation/task/fs.hbs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ui/app/controllers/allocations/allocation/task/fs.js b/ui/app/controllers/allocations/allocation/task/fs.js index 38ff0236de7..84e6be8930d 100644 --- a/ui/app/controllers/allocations/allocation/task/fs.js +++ b/ui/app/controllers/allocations/allocation/task/fs.js @@ -3,8 +3,8 @@ import { computed } from '@ember/object'; import { filterBy } from '@ember/object/computed'; export default Controller.extend({ - directories: filterBy('ls', 'IsDir'), - files: filterBy('ls', 'IsDir', false), + directories: filterBy('directoryEntries', 'IsDir'), + files: filterBy('directoryEntries', 'IsDir', false), pathComponents: computed('pathWithTaskName', function() { return this.pathWithTaskName diff --git a/ui/app/routes/allocations/allocation/task/fs.js b/ui/app/routes/allocations/allocation/task/fs.js index 15cb5f872e2..35ac1e135d6 100644 --- a/ui/app/routes/allocations/allocation/task/fs.js +++ b/ui/app/routes/allocations/allocation/task/fs.js @@ -14,7 +14,7 @@ export default Route.extend({ path: decodedPath, pathWithTaskName, task, - ls: task.ls(pathWithTaskName), + directoryEntries: task.ls(pathWithTaskName), isFile: false, }); } else { @@ -28,8 +28,8 @@ export default Route.extend({ }); }, - setupController(controller, { path, pathWithTaskName, task, ls, isFile }) { + setupController(controller, { path, pathWithTaskName, task, directoryEntries, isFile }) { this._super(...arguments); - controller.setProperties({ path, pathWithTaskName, model: task, ls, isFile }); + controller.setProperties({ path, pathWithTaskName, model: task, directoryEntries, isFile }); }, }); diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 949fd8b5aa2..15f111a3aba 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -28,7 +28,7 @@ {{else}} - {{#if ls}} + {{#if directoryEntries}} From 4e911343c338e841ea6a6e85855dda3d495b7509 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 15:28:22 -0500 Subject: [PATCH 056/101] Change to consistently use double quotes --- .../allocations/allocation/task/fs.hbs | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 15f111a3aba..0d8fc951f0b 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -1,14 +1,14 @@ {{partial "allocations/allocation/task/subnav"}}
      {{#if model.isRunning}} -
      Name
      +
      - - - + + + @@ -41,24 +41,24 @@ - - + + {{/each}} {{#each files as |entry|}} - - + + {{/each}} @@ -66,8 +66,8 @@ From f9a25d920e721d09c8b0665ef62e8a2a72c390b8 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 15:40:58 -0500 Subject: [PATCH 057/101] Extract directory entry component --- ui/app/components/fs-directory-entry.js | 5 +++++ .../allocations/allocation/task/fs.hbs | 22 ++----------------- .../components/fs-directory-entry.hbs | 15 +++++++++++++ 3 files changed, 22 insertions(+), 20 deletions(-) create mode 100644 ui/app/components/fs-directory-entry.js create mode 100644 ui/app/templates/components/fs-directory-entry.hbs diff --git a/ui/app/components/fs-directory-entry.js b/ui/app/components/fs-directory-entry.js new file mode 100644 index 00000000000..4798652642b --- /dev/null +++ b/ui/app/components/fs-directory-entry.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: '', +}); diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 0d8fc951f0b..e37cf037730 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -38,28 +38,10 @@ {{#each directories as |entry|}} - - - - - + {{fs-directory-entry path=path task=model entry=entry}} {{/each}} {{#each files as |entry|}} - - - - - + {{fs-directory-entry path=path task=model entry=entry}} {{/each}} {{else}} diff --git a/ui/app/templates/components/fs-directory-entry.hbs b/ui/app/templates/components/fs-directory-entry.hbs new file mode 100644 index 00000000000..a20a4533653 --- /dev/null +++ b/ui/app/templates/components/fs-directory-entry.hbs @@ -0,0 +1,15 @@ + + + + + From 96200ba9a9f7067d2289cfd37819cc8415fb02ed Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 16:03:05 -0500 Subject: [PATCH 058/101] Add line to turn off table-groups template lint --- ui/app/templates/allocations/allocation/task/fs.hbs | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index e37cf037730..6a4da9e62b6 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -1,6 +1,7 @@ {{partial "allocations/allocation/task/subnav"}}
      {{#if model.isRunning}} + {{! template-lint-disable table-groups }}
      -
      NameFile SizeLast ModifiedNameFile SizeLast Modified
      {{#link-to "allocations.allocation.task.fs" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'folder-outline' class='icon'}} - {{entry.Name}} + {{inline-svg "folder-outline" class="icon"}} + {{entry.Name}} {{/link-to}} {{moment-from entry.ModTime interval=1000}}{{moment-from entry.ModTime interval=1000}}
      {{#link-to "allocations.allocation.task.fs" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg 'file-outline' class='icon'}} - {{entry.Name}} + {{inline-svg "file-outline" class="icon"}} + {{entry.Name}} {{/link-to}} {{format-bytes entry.Size}}{{moment-from entry.ModTime interval=1000}}{{format-bytes entry.Size}}{{moment-from entry.ModTime interval=1000}}
      - {{inline-svg 'alert-circle-outline' class='icon'}} - Directory is empty + {{inline-svg "alert-circle-outline" class="icon"}} + Directory is empty
      - {{#link-to "allocations.allocation.task.fs" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg "folder-outline" class="icon"}} - {{entry.Name}} - {{/link-to}} - {{moment-from entry.ModTime interval=1000}}
      - {{#link-to "allocations.allocation.task.fs" model.allocation model (concat path "/" entry.Name) activeClass="is-active"}} - {{inline-svg "file-outline" class="icon"}} - {{entry.Name}} - {{/link-to}} - {{format-bytes entry.Size}}{{moment-from entry.ModTime interval=1000}}
      + {{#link-to "allocations.allocation.task.fs" task.allocation task (concat path "/" entry.Name) activeClass="is-active"}} + {{#if entry.IsDir}} + {{inline-svg "folder-outline" class="icon"}} + {{else}} + {{inline-svg "file-outline" class="icon"}} + {{/if}} + + {{entry.Name}} + {{/link-to}} + {{#unless entry.IsDir}}{{format-bytes entry.Size}}{{/unless}}{{moment-from entry.ModTime interval=1000}}
      From d34433bfcfb1780fa167f8dca69056e4f4b3d64c Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 16:04:43 -0500 Subject: [PATCH 059/101] Fix indentation --- .../allocations/allocation/task/fs.hbs | 62 +++++++++---------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 6a4da9e62b6..d10586d79e2 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -20,42 +20,42 @@ - {{#if isFile}} - - - - - - {{else}} - {{#if directoryEntries}} - - - - - - - + {{#if isFile}} - {{#each directories as |entry|}} - {{fs-directory-entry path=path task=model entry=entry}} - {{/each}} - {{#each files as |entry|}} - {{fs-directory-entry path=path task=model entry=entry}} - {{/each}} - - {{else}} - - - + + {{else}} + {{#if directoryEntries}} + + + + + + + + + {{#each directories as |entry|}} + {{fs-directory-entry path=path task=model entry=entry}} + {{/each}} + {{#each files as |entry|}} + {{fs-directory-entry path=path task=model entry=entry}} + {{/each}} + + {{else}} + + + + + + {{/if}} {{/if}} - {{/if}}
      -
      placeholder file viewer
      -
      NameFile SizeLast Modified
      - {{inline-svg "alert-circle-outline" class="icon"}} - Directory is empty +
      +
      placeholder file viewer
      NameFile SizeLast Modified
      + {{inline-svg "alert-circle-outline" class="icon"}} + Directory is empty +
      {{else}}
      From 8d390f9f1cd6885bfa2c27a6240b523e15083947 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 16:07:57 -0500 Subject: [PATCH 060/101] Change table container to not be full-width --- ui/app/templates/allocations/allocation/task/fs.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index d10586d79e2..f9db3766c67 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -1,5 +1,5 @@ {{partial "allocations/allocation/task/subnav"}} -
      +
      {{#if model.isRunning}} {{! template-lint-disable table-groups }} From bdf681d55ab0aa02e9a7c4fc1cf97e443e637032 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 16:37:49 -0500 Subject: [PATCH 061/101] Convert task subnav partial to component This will allow the component to encapsulate route-checking logic to show the files link as active both at root and within subdirectories. --- ui/app/components/task-subnav.js | 5 +++++ ui/app/templates/allocations/allocation/task/fs.hbs | 2 +- ui/app/templates/allocations/allocation/task/index.hbs | 2 +- ui/app/templates/allocations/allocation/task/logs.hbs | 2 +- ui/app/templates/allocations/allocation/task/subnav.hbs | 7 ------- ui/app/templates/components/task-subnav.hbs | 7 +++++++ 6 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 ui/app/components/task-subnav.js delete mode 100644 ui/app/templates/allocations/allocation/task/subnav.hbs create mode 100644 ui/app/templates/components/task-subnav.hbs diff --git a/ui/app/components/task-subnav.js b/ui/app/components/task-subnav.js new file mode 100644 index 00000000000..4798652642b --- /dev/null +++ b/ui/app/components/task-subnav.js @@ -0,0 +1,5 @@ +import Component from '@ember/component'; + +export default Component.extend({ + tagName: '', +}); diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index f9db3766c67..f9ce6d92ec2 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -1,4 +1,4 @@ -{{partial "allocations/allocation/task/subnav"}} +{{task-subnav task=model}}
      {{#if model.isRunning}} {{! template-lint-disable table-groups }} diff --git a/ui/app/templates/allocations/allocation/task/index.hbs b/ui/app/templates/allocations/allocation/task/index.hbs index 2e1d56fb0fb..19ddb6fe284 100644 --- a/ui/app/templates/allocations/allocation/task/index.hbs +++ b/ui/app/templates/allocations/allocation/task/index.hbs @@ -1,4 +1,4 @@ -{{partial "allocations/allocation/task/subnav"}} +{{task-subnav task=model}}
      {{#if error}}
      diff --git a/ui/app/templates/allocations/allocation/task/logs.hbs b/ui/app/templates/allocations/allocation/task/logs.hbs index bbbff1ccf9f..3c7bac6dd37 100644 --- a/ui/app/templates/allocations/allocation/task/logs.hbs +++ b/ui/app/templates/allocations/allocation/task/logs.hbs @@ -1,4 +1,4 @@ -{{partial "allocations/allocation/task/subnav"}} +{{task-subnav task=model}}
      {{task-log data-test-task-log allocation=model.allocation task=model.name}}
      diff --git a/ui/app/templates/allocations/allocation/task/subnav.hbs b/ui/app/templates/allocations/allocation/task/subnav.hbs deleted file mode 100644 index 59c8d852a70..00000000000 --- a/ui/app/templates/allocations/allocation/task/subnav.hbs +++ /dev/null @@ -1,7 +0,0 @@ -
      -
        -
      • {{#link-to "allocations.allocation.task.index" model.allocation model activeClass="is-active"}}Overview{{/link-to}}
      • -
      • {{#link-to "allocations.allocation.task.logs" model.allocation model activeClass="is-active"}}Logs{{/link-to}}
      • -
      • {{#link-to "allocations.allocation.task.fs-root" model.allocation model activeClass="is-active"}}Files{{/link-to}}
      • -
      -
      diff --git a/ui/app/templates/components/task-subnav.hbs b/ui/app/templates/components/task-subnav.hbs new file mode 100644 index 00000000000..e6238438728 --- /dev/null +++ b/ui/app/templates/components/task-subnav.hbs @@ -0,0 +1,7 @@ +
      +
        +
      • {{#link-to "allocations.allocation.task.index" task.allocation task activeClass="is-active"}}Overview{{/link-to}}
      • +
      • {{#link-to "allocations.allocation.task.logs" task.allocation task activeClass="is-active"}}Logs{{/link-to}}
      • +
      • {{#link-to "allocations.allocation.task.fs-root" task.allocation task activeClass="is-active"}}Files{{/link-to}}
      • +
      +
      From 19313e63d2548535d5a10cc2fbf55a0a3f7bdef0 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Wed, 26 Jun 2019 16:44:46 -0500 Subject: [PATCH 062/101] Change files link to be active at all levels --- ui/app/components/task-subnav.js | 9 +++++++++ ui/app/templates/components/task-subnav.hbs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ui/app/components/task-subnav.js b/ui/app/components/task-subnav.js index 4798652642b..0aab1e6f459 100644 --- a/ui/app/components/task-subnav.js +++ b/ui/app/components/task-subnav.js @@ -1,5 +1,14 @@ import Component from '@ember/component'; +import { inject as service } from '@ember/service'; +import { equal, or } from '@ember/object/computed'; export default Component.extend({ + router: service(), + tagName: '', + + fsIsActive: equal('router.currentRouteName', 'allocations.allocation.task.fs'), + fsRootIsActive: equal('router.currentRouteName', 'allocations.allocation.task.fs-root'), + + filesLinkActive: or('fsIsActive', 'fsRootIsActive'), }); diff --git a/ui/app/templates/components/task-subnav.hbs b/ui/app/templates/components/task-subnav.hbs index e6238438728..974d983eea7 100644 --- a/ui/app/templates/components/task-subnav.hbs +++ b/ui/app/templates/components/task-subnav.hbs @@ -2,6 +2,6 @@
      • {{#link-to "allocations.allocation.task.index" task.allocation task activeClass="is-active"}}Overview{{/link-to}}
      • {{#link-to "allocations.allocation.task.logs" task.allocation task activeClass="is-active"}}Logs{{/link-to}}
      • -
      • {{#link-to "allocations.allocation.task.fs-root" task.allocation task activeClass="is-active"}}Files{{/link-to}}
      • +
      • {{#link-to "allocations.allocation.task.fs-root" task.allocation task class=(if filesLinkActive 'is-active')}}Files{{/link-to}}
      From 3313a2efef46805c70e07787dfa0686fca3e7d6f Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 01:19:19 -0500 Subject: [PATCH 063/101] Add prototype loading animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This only applies to directory entries and not breadcrumbs, where it would either cause overlap or maybe weird jumping, but it’s more for demonstration/conversation. Thanks to @StephanWagner for the examples here: https://stephanwagner.me/only-css-loading-spinner --- ui/app/styles/components/allocation-fs.scss | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss index 4df497b88ab..0d9f1363d1a 100644 --- a/ui/app/styles/components/allocation-fs.scss +++ b/ui/app/styles/components/allocation-fs.scss @@ -1,3 +1,9 @@ +@keyframes spinner { + to { + transform: rotate(360deg); + } +} + .fs-explorer.table { width: 100%; @@ -5,12 +11,26 @@ a { text-decoration: none; color: inherit; + position: relative; &:hover { .name { text-decoration: underline; } } + + &.ember-transitioning-in::after { + content: ''; + box-sizing: border-box; + position: absolute; + right: -25px; + width: 20px; + height: 20px; + border-radius: 50%; + border: 2px solid $light; + border-top-color: $grey-light; + animation: spinner 0.6s linear infinite; + } } } } From ac94741d08db00bd8085f14700fbe3cea5097437 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 11:02:09 -0500 Subject: [PATCH 064/101] Replace loading animation with Bulma .is-loading --- ui/app/styles/components/allocation-fs.scss | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss index 0d9f1363d1a..0109e735035 100644 --- a/ui/app/styles/components/allocation-fs.scss +++ b/ui/app/styles/components/allocation-fs.scss @@ -19,17 +19,20 @@ } } + // This is copied from Bulma’s .button.is-loading::after &.ember-transitioning-in::after { + animation: spinAround 500ms infinite linear; + border: 2px solid $grey-light; + border-radius: 290486px; + border-right-color: transparent; + border-top-color: transparent; content: ''; - box-sizing: border-box; + display: block; + height: 1em; + width: 1em; position: absolute; - right: -25px; - width: 20px; - height: 20px; - border-radius: 50%; - border: 2px solid $light; - border-top-color: $grey-light; - animation: spinner 0.6s linear infinite; + right: -1.5em; + top: calc(50% - (1em / 2)); } } } From 74fc0ced054aec3532766a4d5292bac4650cc571 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 11:24:59 -0500 Subject: [PATCH 065/101] Add loading animation for breadcrumb links I thought I would hate the jumping when the animation appears but it actually seems fine! --- ui/app/styles/components/allocation-fs.scss | 50 ++++++++++++++------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/ui/app/styles/components/allocation-fs.scss b/ui/app/styles/components/allocation-fs.scss index 0109e735035..3a276801f48 100644 --- a/ui/app/styles/components/allocation-fs.scss +++ b/ui/app/styles/components/allocation-fs.scss @@ -11,29 +11,12 @@ a { text-decoration: none; color: inherit; - position: relative; &:hover { .name { text-decoration: underline; } } - - // This is copied from Bulma’s .button.is-loading::after - &.ember-transitioning-in::after { - animation: spinAround 500ms infinite linear; - border: 2px solid $grey-light; - border-radius: 290486px; - border-right-color: transparent; - border-top-color: transparent; - content: ''; - display: block; - height: 1em; - width: 1em; - position: absolute; - right: -1.5em; - top: calc(50% - (1em / 2)); - } } } } @@ -58,3 +41,36 @@ color: $black; } } + +.fs-explorer.table, +.breadcrumb.fs { + a { + position: relative; + + // This is copied from Bulma’s .button.is-loading::after + &.ember-transitioning-in::after { + animation: spinAround 500ms infinite linear; + border: 2px solid $grey-light; + border-radius: 290486px; + border-right-color: transparent; + border-top-color: transparent; + content: ''; + display: block; + height: 1em; + width: 1em; + position: absolute; + right: -1.5em; + top: calc(50% - (1em / 2)); + } + } +} + +.breadcrumb.fs { + a.ember-transitioning-in { + margin-right: 1.5em; + + &::after { + right: -1em; + } + } +} From 0ca2353a5a021cbb720514037351b3ee64c451e6 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 11:47:34 -0500 Subject: [PATCH 066/101] Change width of name column In the absence of a flex-grow-like quality for tables, this handles more viewport widths. --- ui/app/templates/allocations/allocation/task/fs.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index f9ce6d92ec2..9a0a278ce61 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -32,7 +32,7 @@ {{#if directoryEntries}}
      - + From d7232faa20c0650b053303b281f605c20f2ca93f Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 12:14:01 -0500 Subject: [PATCH 067/101] Combine path tests into root FS file --- ui/tests/acceptance/task-fs-path-test.js | 108 --------------------- ui/tests/acceptance/task-fs-test.js | 86 ++++++++++++++++ ui/tests/pages/allocations/task/fs.js | 35 ++++++- ui/tests/pages/allocations/task/fs/path.js | 37 ------- 4 files changed, 119 insertions(+), 147 deletions(-) delete mode 100644 ui/tests/acceptance/task-fs-path-test.js delete mode 100644 ui/tests/pages/allocations/task/fs/path.js diff --git a/ui/tests/acceptance/task-fs-path-test.js b/ui/tests/acceptance/task-fs-path-test.js deleted file mode 100644 index 1fd6e21864e..00000000000 --- a/ui/tests/acceptance/task-fs-path-test.js +++ /dev/null @@ -1,108 +0,0 @@ -import { currentURL } from '@ember/test-helpers'; -import { Promise } from 'rsvp'; -import { module } from 'qunit'; -import { setupApplicationTest, test } from 'ember-qunit'; -import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; -import Path from 'nomad-ui/tests/pages/allocations/task/fs/path'; - -let allocation; -let task; - -module('Acceptance | task fs path', function(hooks) { - setupApplicationTest(hooks); - setupMirage(hooks); - - hooks.beforeEach(async function() { - server.create('agent'); - server.create('node', 'forceIPv4'); - const job = server.create('job', { createAllocations: false }); - - allocation = server.create('allocation', { jobId: job.id, clientStatus: 'running' }); - task = server.schema.taskStates.where({ allocationId: allocation.id }).models[0]; - }); - - test('visiting /allocations/:allocation_id/:task_name/fs/:path', async function(assert) { - const paths = ['some-file.log', 'a/deep/path/to/a/file.log', '/', 'Unicode™®']; - - const testPath = async filePath => { - await Path.visit({ id: allocation.id, name: task.name, path: filePath }); - assert.equal( - currentURL(), - `/allocations/${allocation.id}/${task.name}/fs/${encodeURIComponent(filePath)}`, - 'No redirect' - ); - assert.equal(Path.breadcrumbsText, `${task.name} ${filePath.replace(/\//g, ' ')}`.trim()); - }; - - await paths.reduce(async (prev, filePath) => { - await prev; - return testPath(filePath); - }, Promise.resolve()); - }); - - test('navigating allocation filesystem', async function(assert) { - await Path.visit({ id: allocation.id, name: task.name, path: '/' }); - - assert.ok(Path.fileViewer.isHidden); - - assert.equal(Path.directoryEntries.length, 4); - - assert.equal(Path.breadcrumbsText, task.name); - - assert.equal(Path.breadcrumbs.length, 1); - assert.ok(Path.breadcrumbs[0].isActive); - assert.equal(Path.breadcrumbs[0].text, task.name); - - assert.equal(Path.directoryEntries[0].name, 'directory', 'directories should come first'); - assert.ok(Path.directoryEntries[0].isDirectory); - assert.equal(Path.directoryEntries[0].size, '', 'directory sizes are hidden'); - assert.equal(Path.directoryEntries[0].lastModified, 'a year ago'); - - assert.equal(Path.directoryEntries[2].name, '🤩.txt'); - assert.ok(Path.directoryEntries[2].isFile); - assert.equal(Path.directoryEntries[2].size, '1 KiB'); - assert.equal(Path.directoryEntries[2].lastModified, '2 days ago'); - - assert.equal(Path.directoryEntries[3].name, '🙌🏿.txt'); - - await Path.directoryEntries[0].visit(); - - assert.equal(Path.directoryEntries.length, 1); - - assert.equal(Path.breadcrumbs.length, 2); - assert.equal(Path.breadcrumbsText, `${task.name} directory`); - - assert.notOk(Path.breadcrumbs[0].isActive); - - assert.equal(Path.breadcrumbs[1].text, 'directory'); - assert.ok(Path.breadcrumbs[1].isActive); - - await Path.directoryEntries[0].visit(); - - assert.equal(Path.directoryEntries.length, 1); - - assert.equal(Path.breadcrumbs.length, 3); - assert.equal(Path.breadcrumbsText, `${task.name} directory another`); - assert.equal(Path.breadcrumbs[2].text, 'another'); - - await Path.breadcrumbs[1].visit(); - assert.equal(Path.breadcrumbsText, `${task.name} directory`); - assert.equal(Path.breadcrumbs.length, 2); - }); - - test('viewing a file', async function(assert) { - await Path.visit({ id: allocation.id, name: task.name, path: '/' }); - await Path.directoryEntries[2].visit(); - - assert.equal(Path.breadcrumbsText, `${task.name} 🤩.txt`); - - assert.ok(Path.fileViewer.isPresent); - }); - - test('viewing an empty directory', async function(assert) { - await Path.visit({ id: allocation.id, name: task.name, path: '/empty-directory' }); - - assert.equal(Path.directoryEntries.length, 1); - assert.ok(Path.directoryEntries[0].isEmpty); - }); -}); diff --git a/ui/tests/acceptance/task-fs-test.js b/ui/tests/acceptance/task-fs-test.js index 7fcc5f730de..ef4ce0b3108 100644 --- a/ui/tests/acceptance/task-fs-test.js +++ b/ui/tests/acceptance/task-fs-test.js @@ -1,4 +1,5 @@ import { currentURL } from '@ember/test-helpers'; +import { Promise } from 'rsvp'; import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; @@ -37,4 +38,89 @@ module('Acceptance | task fs', function(hooks) { 'Empty state explains the condition' ); }); + + test('visiting /allocations/:allocation_id/:task_name/fs/:path', async function(assert) { + const paths = ['some-file.log', 'a/deep/path/to/a/file.log', '/', 'Unicode™®']; + + const testPath = async filePath => { + await FS.visitPath({ id: allocation.id, name: task.name, path: filePath }); + assert.equal( + currentURL(), + `/allocations/${allocation.id}/${task.name}/fs/${encodeURIComponent(filePath)}`, + 'No redirect' + ); + assert.equal(FS.breadcrumbsText, `${task.name} ${filePath.replace(/\//g, ' ')}`.trim()); + }; + + await paths.reduce(async (prev, filePath) => { + await prev; + return testPath(filePath); + }, Promise.resolve()); + }); + + test('navigating allocation filesystem', async function(assert) { + await FS.visitPath({ id: allocation.id, name: task.name, path: '/' }); + + assert.ok(FS.fileViewer.isHidden); + + assert.equal(FS.directoryEntries.length, 4); + + assert.equal(FS.breadcrumbsText, task.name); + + assert.equal(FS.breadcrumbs.length, 1); + assert.ok(FS.breadcrumbs[0].isActive); + assert.equal(FS.breadcrumbs[0].text, task.name); + + assert.equal(FS.directoryEntries[0].name, 'directory', 'directories should come first'); + assert.ok(FS.directoryEntries[0].isDirectory); + assert.equal(FS.directoryEntries[0].size, '', 'directory sizes are hidden'); + assert.equal(FS.directoryEntries[0].lastModified, 'a year ago'); + + assert.equal(FS.directoryEntries[2].name, '🤩.txt'); + assert.ok(FS.directoryEntries[2].isFile); + assert.equal(FS.directoryEntries[2].size, '1 KiB'); + assert.equal(FS.directoryEntries[2].lastModified, '2 days ago'); + + assert.equal(FS.directoryEntries[3].name, '🙌🏿.txt'); + + await FS.directoryEntries[0].visit(); + + assert.equal(FS.directoryEntries.length, 1); + + assert.equal(FS.breadcrumbs.length, 2); + assert.equal(FS.breadcrumbsText, `${task.name} directory`); + + assert.notOk(FS.breadcrumbs[0].isActive); + + assert.equal(FS.breadcrumbs[1].text, 'directory'); + assert.ok(FS.breadcrumbs[1].isActive); + + await FS.directoryEntries[0].visit(); + + assert.equal(FS.directoryEntries.length, 1); + + assert.equal(FS.breadcrumbs.length, 3); + assert.equal(FS.breadcrumbsText, `${task.name} directory another`); + assert.equal(FS.breadcrumbs[2].text, 'another'); + + await FS.breadcrumbs[1].visit(); + assert.equal(FS.breadcrumbsText, `${task.name} directory`); + assert.equal(FS.breadcrumbs.length, 2); + }); + + test('viewing a file', async function(assert) { + await FS.visitPath({ id: allocation.id, name: task.name, path: '/' }); + await FS.directoryEntries[2].visit(); + + assert.equal(FS.breadcrumbsText, `${task.name} 🤩.txt`); + + assert.ok(FS.fileViewer.isPresent); + }); + + test('viewing an empty directory', async function(assert) { + await FS.visitPath({ id: allocation.id, name: task.name, path: '/empty-directory' }); + + assert.equal(FS.directoryEntries.length, 1); + assert.ok(FS.directoryEntries[0].isEmpty); + }); }); diff --git a/ui/tests/pages/allocations/task/fs.js b/ui/tests/pages/allocations/task/fs.js index d133d6824e8..cad5e0f7981 100644 --- a/ui/tests/pages/allocations/task/fs.js +++ b/ui/tests/pages/allocations/task/fs.js @@ -1,9 +1,40 @@ -import { create, isPresent, text, visitable } from 'ember-cli-page-object'; +import { + collection, + clickable, + create, + hasClass, + isPresent, + text, + visitable, +} from 'ember-cli-page-object'; export default create({ visit: visitable('/allocations/:id/:name/fs'), + visitPath: visitable('/allocations/:id/:name/fs/:path'), - hasFiles: isPresent('[data-test-file-explorer]'), + fileViewer: { + scope: '[data-test-file-viewer]', + }, + + breadcrumbsText: text('[data-test-fs-breadcrumbs]'), + + breadcrumbs: collection('[data-test-fs-breadcrumbs] li', { + visit: clickable('a'), + isActive: hasClass('is-active'), + }), + + directoryEntries: collection('[data-test-entry]', { + name: text('[data-test-name]'), + + isFile: isPresent('[data-test-file-icon]'), + isDirectory: isPresent('[data-test-directory-icon]'), + isEmpty: isPresent('[data-test-empty-icon]'), + + size: text('[data-test-size]'), + lastModified: text('[data-test-last-modified]'), + + visit: clickable('a'), + }), hasEmptyState: isPresent('[data-test-not-running]'), emptyState: { diff --git a/ui/tests/pages/allocations/task/fs/path.js b/ui/tests/pages/allocations/task/fs/path.js deleted file mode 100644 index 2e3411104cc..00000000000 --- a/ui/tests/pages/allocations/task/fs/path.js +++ /dev/null @@ -1,37 +0,0 @@ -import { - clickable, - collection, - create, - hasClass, - isPresent, - text, - visitable, -} from 'ember-cli-page-object'; - -export default create({ - visit: visitable('/allocations/:id/:name/fs/:path'), - - fileViewer: { - scope: '[data-test-file-viewer]', - }, - - breadcrumbsText: text('[data-test-fs-breadcrumbs]'), - - breadcrumbs: collection('[data-test-fs-breadcrumbs] li', { - visit: clickable('a'), - isActive: hasClass('is-active'), - }), - - directoryEntries: collection('[data-test-entry]', { - name: text('[data-test-name]'), - - isFile: isPresent('[data-test-file-icon]'), - isDirectory: isPresent('[data-test-directory-icon]'), - isEmpty: isPresent('[data-test-empty-icon]'), - - size: text('[data-test-size]'), - lastModified: text('[data-test-last-modified]'), - - visit: clickable('a'), - }), -}); From 23623ec070609ed0ac779fa4dc0d04b0725a6389 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 13:00:55 -0500 Subject: [PATCH 068/101] Combine directory and file iterations --- ui/app/templates/allocations/allocation/task/fs.hbs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 9a0a278ce61..54f131c51cc 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -38,10 +38,7 @@ - {{#each directories as |entry|}} - {{fs-directory-entry path=path task=model entry=entry}} - {{/each}} - {{#each files as |entry|}} + {{#each (append directories files) as |entry|}} {{fs-directory-entry path=path task=model entry=entry}} {{/each}} From 6aae341dd410841709bfaa6ff24e3fbc3b6a5c91 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 13:11:41 -0500 Subject: [PATCH 069/101] Remove doubled slashes in directory entry paths --- ui/app/components/fs-directory-entry.js | 8 ++++++++ ui/app/templates/components/fs-directory-entry.hbs | 2 +- ui/tests/acceptance/task-fs-test.js | 1 + ui/tests/pages/allocations/task/fs.js | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/ui/app/components/fs-directory-entry.js b/ui/app/components/fs-directory-entry.js index 4798652642b..7b1e0dd5dff 100644 --- a/ui/app/components/fs-directory-entry.js +++ b/ui/app/components/fs-directory-entry.js @@ -1,5 +1,13 @@ import Component from '@ember/component'; +import { computed } from '@ember/object'; export default Component.extend({ tagName: '', + + pathToEntry: computed('path', 'entry.Name', function() { + const pathWithNoLeadingSlash = this.get('path').replace(/^\//, ''); + const name = this.get('entry.Name'); + + return `${pathWithNoLeadingSlash}/${name}`; + }), }); diff --git a/ui/app/templates/components/fs-directory-entry.hbs b/ui/app/templates/components/fs-directory-entry.hbs index a20a4533653..9d0becad286 100644 --- a/ui/app/templates/components/fs-directory-entry.hbs +++ b/ui/app/templates/components/fs-directory-entry.hbs @@ -1,6 +1,6 @@ diff --git a/ui/app/templates/components/fs-directory-entry.hbs b/ui/app/templates/components/fs-directory-entry.hbs index 7498212cdb3..8009f1c8e7b 100644 --- a/ui/app/templates/components/fs-directory-entry.hbs +++ b/ui/app/templates/components/fs-directory-entry.hbs @@ -2,9 +2,9 @@ - + From ea4fd6867f81954aadbf07e36c6671f76f6cd5ec Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 2 Jul 2019 13:32:26 -0500 Subject: [PATCH 101/101] Add notifyError calls to route --- .../routes/allocations/allocation/task/fs.js | 38 ++++++++++--------- ui/tests/acceptance/task-fs-test.js | 6 ++- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/ui/app/routes/allocations/allocation/task/fs.js b/ui/app/routes/allocations/allocation/task/fs.js index 32922603c45..f592e77a0df 100644 --- a/ui/app/routes/allocations/allocation/task/fs.js +++ b/ui/app/routes/allocations/allocation/task/fs.js @@ -1,5 +1,6 @@ import Route from '@ember/routing/route'; import RSVP from 'rsvp'; +import notifyError from 'nomad-ui/utils/notify-error'; export default Route.extend({ model({ path = '/' }) { @@ -8,25 +9,28 @@ export default Route.extend({ const pathWithTaskName = `${task.name}${decodedPath.startsWith('/') ? '' : '/'}${decodedPath}`; - return task.stat(pathWithTaskName).then(statJson => { - if (statJson.IsDir) { - return RSVP.hash({ - path: decodedPath, - task, - directoryEntries: task.ls(pathWithTaskName), - isFile: false, - }); - } else { - return { - path: decodedPath, - task, - isFile: true, - }; - } - }); + return task + .stat(pathWithTaskName) + .then(statJson => { + if (statJson.IsDir) { + return RSVP.hash({ + path: decodedPath, + task, + directoryEntries: task.ls(pathWithTaskName).catch(notifyError(this)), + isFile: false, + }); + } else { + return { + path: decodedPath, + task, + isFile: true, + }; + } + }) + .catch(notifyError(this)); }, - setupController(controller, { path, task, directoryEntries, isFile }) { + setupController(controller, { path, task, directoryEntries, isFile } = {}) { this._super(...arguments); controller.setProperties({ path, task, directoryEntries, isFile }); }, diff --git a/ui/tests/acceptance/task-fs-test.js b/ui/tests/acceptance/task-fs-test.js index be77731a9c3..5e42a2eb3c1 100644 --- a/ui/tests/acceptance/task-fs-test.js +++ b/ui/tests/acceptance/task-fs-test.js @@ -1,4 +1,4 @@ -import { currentURL } from '@ember/test-helpers'; +import { currentURL, visit } from '@ember/test-helpers'; import { Promise } from 'rsvp'; import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; @@ -153,6 +153,8 @@ module('Acceptance | task fs', function(hooks) { await FS.visitPath({ id: allocation.id, name: task.name, path: '/what-is-this' }); assert.equal(FS.error.title, 'Not Found', '500 is interpreted as 404'); + await visit('/'); + this.server.get('/client/fs/stat/:allocation_id', () => { return new Response(999); }); @@ -169,6 +171,8 @@ module('Acceptance | task fs', function(hooks) { await FS.visitPath({ id: allocation.id, name: task.name, path: '/what-is-this' }); assert.equal(FS.error.title, 'Not Found', '500 is interpreted as 404'); + await visit('/'); + this.server.get('/client/fs/ls/:allocation_id', () => { return new Response(999); });
      NameName File Size Last Modified
      - {{#link-to "allocations.allocation.task.fs" task.allocation task (concat path "/" entry.Name) activeClass="is-active"}} + {{#link-to "allocations.allocation.task.fs" task.allocation task pathToEntry activeClass="is-active"}} {{#if entry.IsDir}} {{inline-svg "folder-outline" class="icon"}} {{else}} diff --git a/ui/tests/acceptance/task-fs-test.js b/ui/tests/acceptance/task-fs-test.js index ef4ce0b3108..d396046cfbd 100644 --- a/ui/tests/acceptance/task-fs-test.js +++ b/ui/tests/acceptance/task-fs-test.js @@ -98,6 +98,7 @@ module('Acceptance | task fs', function(hooks) { await FS.directoryEntries[0].visit(); assert.equal(FS.directoryEntries.length, 1); + assert.notOk(FS.directoryEntries[0].path.includes('//')); assert.equal(FS.breadcrumbs.length, 3); assert.equal(FS.breadcrumbsText, `${task.name} directory another`); diff --git a/ui/tests/pages/allocations/task/fs.js b/ui/tests/pages/allocations/task/fs.js index cad5e0f7981..68a77256ee5 100644 --- a/ui/tests/pages/allocations/task/fs.js +++ b/ui/tests/pages/allocations/task/fs.js @@ -1,4 +1,5 @@ import { + attribute, collection, clickable, create, @@ -34,6 +35,7 @@ export default create({ lastModified: text('[data-test-last-modified]'), visit: clickable('a'), + path: attribute('href', 'a'), }), hasEmptyState: isPresent('[data-test-not-running]'), From d0f60284d01ef7b5d67b79b117561521996c1bec Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Thu, 27 Jun 2019 13:22:53 -0500 Subject: [PATCH 070/101] Remove doubled slashes from breadcrumb paths --- ui/app/controllers/allocations/allocation/task/fs.js | 8 +++++--- ui/app/templates/allocations/allocation/task/fs.hbs | 5 +++++ ui/tests/acceptance/task-fs-test.js | 3 +++ ui/tests/pages/allocations/task/fs.js | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/ui/app/controllers/allocations/allocation/task/fs.js b/ui/app/controllers/allocations/allocation/task/fs.js index 84e6be8930d..af75fd71d54 100644 --- a/ui/app/controllers/allocations/allocation/task/fs.js +++ b/ui/app/controllers/allocations/allocation/task/fs.js @@ -6,14 +6,16 @@ export default Controller.extend({ directories: filterBy('directoryEntries', 'IsDir'), files: filterBy('directoryEntries', 'IsDir', false), - pathComponents: computed('pathWithTaskName', function() { - return this.pathWithTaskName + pathComponents: computed('path', 'model.name', function() { + return this.path .split('/') .reject(s => s === '') .reduce( (componentsAndPath, component, componentIndex, components) => { if (componentIndex) { componentsAndPath.path = `${componentsAndPath.path}/${component}`; + } else { + componentsAndPath.path = component; } componentsAndPath.components.push({ @@ -26,7 +28,7 @@ export default Controller.extend({ }, { components: [], - path: '/', + path: '', } ).components; }), diff --git a/ui/app/templates/allocations/allocation/task/fs.hbs b/ui/app/templates/allocations/allocation/task/fs.hbs index 54f131c51cc..7eebacddd4b 100644 --- a/ui/app/templates/allocations/allocation/task/fs.hbs +++ b/ui/app/templates/allocations/allocation/task/fs.hbs @@ -8,6 +8,11 @@
      - {{inline-svg "alert-circle-outline" class="icon"}} + {{x-icon "alert-circle-outline"}} Directory is empty
      {{#link-to "allocations.allocation.task.fs" task.allocation task pathToEntry activeClass="is-active"}} {{#if entry.IsDir}} - {{inline-svg "folder-outline" class="icon"}} + {{x-icon "folder-outline"}} {{else}} - {{inline-svg "file-outline" class="icon"}} + {{x-icon "file-outline"}} {{/if}} {{entry.Name}} From 437492bac9d1f4587385175acbff29ea0d88a1c6 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 2 Jul 2019 11:41:00 -0500 Subject: [PATCH 097/101] Add Mirage handlers for other-host FS requests --- ui/mirage/config.js | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/ui/mirage/config.js b/ui/mirage/config.js index b103f2a2204..777124d7b97 100644 --- a/ui/mirage/config.js +++ b/ui/mirage/config.js @@ -305,15 +305,7 @@ export default function() { return logEncode(logFrames, logFrames.length - 1); }; - // Client requests are available on the server and the client - this.put('/client/allocation/:id/restart', function() { - return new Response(204, {}, ''); - }); - - this.get('/client/allocation/:id/stats', clientAllocationStatsHandler); - this.get('/client/fs/logs/:allocation_id', clientAllocationLog); - - this.get('/client/fs/ls/:allocation_id', (schema, { queryParams }) => { + const clientAllocationFSLsHandler = function(schema, { queryParams }) { if (queryParams.path.endsWith('empty-directory')) { return []; } else if (queryParams.path.endsWith('directory')) { @@ -364,14 +356,25 @@ export default function() { }, ]; } - }); + }; - this.get('/client/fs/stat/:allocation_id', (schema, { queryParams }) => { + const clientAllocationFSStatHandler = function(schema, { queryParams }) { return { IsDir: !queryParams.path.endsWith('.txt'), }; + }; + + // Client requests are available on the server and the client + this.put('/client/allocation/:id/restart', function() { + return new Response(204, {}, ''); }); + this.get('/client/allocation/:id/stats', clientAllocationStatsHandler); + this.get('/client/fs/logs/:allocation_id', clientAllocationLog); + + this.get('/client/fs/ls/:allocation_id', clientAllocationFSLsHandler); + this.get('/client/fs/stat/:allocation_id', clientAllocationFSStatHandler); + this.get('/client/stats', function({ clientStats }, { queryParams }) { const seed = Math.random(); if (seed > 0.8) { @@ -392,6 +395,9 @@ export default function() { this.get(`http://${host}/v1/client/allocation/:id/stats`, clientAllocationStatsHandler); this.get(`http://${host}/v1/client/fs/logs/:allocation_id`, clientAllocationLog); + this.get(`http://${host}/v1/client/fs/ls/:allocation_id`, clientAllocationFSLsHandler); + this.get(`http://${host}/v1/client/stat/ls/:allocation_id`, clientAllocationFSStatHandler); + this.get(`http://${host}/v1/client/stats`, function({ clientStats }) { return this.serialize(clientStats.find(host)); }); From 2d221bd8907d3e9b6a9d18fa5fbceb87b973b7a3 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 2 Jul 2019 11:47:41 -0500 Subject: [PATCH 098/101] Add assertion explanations for double-slash --- ui/tests/acceptance/task-fs-test.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ui/tests/acceptance/task-fs-test.js b/ui/tests/acceptance/task-fs-test.js index 9a07630b564..30192e9680b 100644 --- a/ui/tests/acceptance/task-fs-test.js +++ b/ui/tests/acceptance/task-fs-test.js @@ -105,14 +105,23 @@ module('Acceptance | task fs', function(hooks) { await FS.directoryEntries[0].visit(); assert.equal(FS.directoryEntries.length, 1); - assert.notOk(FS.directoryEntries[0].path.includes('//')); + assert.notOk( + FS.directoryEntries[0].path.includes('//'), + 'paths shouldn’t have redundant separators' + ); assert.equal(FS.breadcrumbs.length, 3); assert.equal(FS.breadcrumbsText, 'task-name directory another'); assert.equal(FS.breadcrumbs[2].text, 'another'); - assert.notOk(FS.breadcrumbs[0].path.includes('//')); - assert.notOk(FS.breadcrumbs[1].path.includes('//')); + assert.notOk( + FS.breadcrumbs[0].path.includes('//'), + 'paths shouldn’t have redundant separators' + ); + assert.notOk( + FS.breadcrumbs[1].path.includes('//'), + 'paths shouldn’t have redundant separators' + ); await FS.breadcrumbs[1].visit(); assert.equal(FS.breadcrumbsText, 'task-name directory'); From d18ede9ecc526c1dcdc06466565cd13128ee0f72 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 2 Jul 2019 12:00:47 -0500 Subject: [PATCH 099/101] Fix another double-slash issue --- ui/app/components/fs-directory-entry.js | 7 ++++++- ui/tests/acceptance/task-fs-test.js | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/ui/app/components/fs-directory-entry.js b/ui/app/components/fs-directory-entry.js index 7b1e0dd5dff..73a52742154 100644 --- a/ui/app/components/fs-directory-entry.js +++ b/ui/app/components/fs-directory-entry.js @@ -1,5 +1,6 @@ import Component from '@ember/component'; import { computed } from '@ember/object'; +import { isEmpty } from '@ember/utils'; export default Component.extend({ tagName: '', @@ -8,6 +9,10 @@ export default Component.extend({ const pathWithNoLeadingSlash = this.get('path').replace(/^\//, ''); const name = this.get('entry.Name'); - return `${pathWithNoLeadingSlash}/${name}`; + if (isEmpty(pathWithNoLeadingSlash)) { + return name; + } else { + return `${pathWithNoLeadingSlash}/${name}`; + } }), }); diff --git a/ui/tests/acceptance/task-fs-test.js b/ui/tests/acceptance/task-fs-test.js index 30192e9680b..be77731a9c3 100644 --- a/ui/tests/acceptance/task-fs-test.js +++ b/ui/tests/acceptance/task-fs-test.js @@ -81,6 +81,7 @@ module('Acceptance | task fs', function(hooks) { assert.ok(directory.isDirectory); assert.equal(directory.size, '', 'directory sizes are hidden'); assert.equal(directory.lastModified, 'a year ago'); + assert.notOk(directory.path.includes('//'), 'paths shouldn’t have redundant separators'); }); FS.directoryEntries[2].as(file => { From 24c25f65012e16c59f683be3b43d345d236bb209 Mon Sep 17 00:00:00 2001 From: Buck Doyle Date: Tue, 2 Jul 2019 12:21:04 -0500 Subject: [PATCH 100/101] Update entry hover with standard timestamp format --- ui/app/templates/components/fs-directory-entry.hbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/templates/components/fs-directory-entry.hbs b/ui/app/templates/components/fs-directory-entry.hbs index 8009f1c8e7b..11c4df03208 100644 --- a/ui/app/templates/components/fs-directory-entry.hbs +++ b/ui/app/templates/components/fs-directory-entry.hbs @@ -11,5 +11,5 @@ {{/link-to}} {{#unless entry.IsDir}}{{format-bytes entry.Size}}{{/unless}}{{moment-from entry.ModTime interval=1000}}{{moment-from entry.ModTime interval=1000}}