@fleetbase/solid-engine 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE.md +651 -21
  2. package/README.md +89 -18
  3. package/addon/components/explorer-header.hbs +18 -0
  4. package/addon/components/explorer-header.js +25 -0
  5. package/addon/components/modals/backup-pod.hbs +3 -0
  6. package/addon/components/modals/create-pod.hbs +5 -0
  7. package/addon/components/modals/resync-pod.hbs +3 -0
  8. package/addon/components/table/cell/pod-content-actions.hbs +32 -0
  9. package/addon/components/table/cell/pod-content-actions.js +73 -0
  10. package/addon/components/table/cell/pod-content-name.hbs +8 -0
  11. package/addon/components/table/cell/pod-content-name.js +16 -0
  12. package/addon/controllers/account.js +130 -0
  13. package/addon/controllers/application.js +16 -13
  14. package/addon/controllers/home.js +23 -0
  15. package/addon/controllers/pods/explorer/content.js +12 -0
  16. package/addon/controllers/pods/explorer.js +149 -0
  17. package/addon/controllers/pods/index/pod.js +12 -0
  18. package/addon/controllers/pods/index.js +137 -0
  19. package/addon/routes/account.js +3 -0
  20. package/addon/routes/home.js +3 -0
  21. package/addon/routes/pods/explorer/content.js +10 -0
  22. package/addon/routes/pods/explorer.js +44 -0
  23. package/addon/routes/pods/index/pod.js +3 -0
  24. package/addon/routes/pods/index.js +21 -0
  25. package/addon/routes.js +12 -1
  26. package/addon/services/explorer-state.js +101 -0
  27. package/addon/styles/solid-engine.css +46 -0
  28. package/addon/templates/account.hbs +42 -0
  29. package/addon/templates/application.hbs +17 -12
  30. package/addon/templates/home.hbs +11 -0
  31. package/addon/templates/pods/explorer/content.hbs +19 -0
  32. package/addon/templates/pods/explorer.hbs +20 -0
  33. package/addon/templates/pods/index/pod.hbs +11 -0
  34. package/addon/templates/pods/index.hbs +19 -0
  35. package/app/components/explorer-header.js +1 -0
  36. package/app/components/modals/backup-pod.js +1 -0
  37. package/app/components/modals/create-pod.js +1 -0
  38. package/app/components/modals/resync-pod.js +1 -0
  39. package/app/components/table/cell/pod-content-actions.js +1 -0
  40. package/app/components/table/cell/pod-content-name.js +1 -0
  41. package/app/controllers/account.js +1 -0
  42. package/app/controllers/home.js +1 -0
  43. package/app/controllers/pods/explorer/content.js +1 -0
  44. package/app/controllers/pods/explorer.js +1 -0
  45. package/app/controllers/pods/index/pod.js +1 -0
  46. package/app/controllers/pods/index.js +1 -0
  47. package/app/routes/account.js +1 -0
  48. package/app/routes/home.js +1 -0
  49. package/app/routes/pods/explorer/content.js +1 -0
  50. package/app/routes/pods/explorer.js +1 -0
  51. package/app/routes/pods/index/pod.js +1 -0
  52. package/app/routes/pods/index.js +1 -0
  53. package/app/services/explorer-state.js +1 -0
  54. package/app/templates/account.js +1 -0
  55. package/app/templates/home.js +1 -0
  56. package/app/templates/pods/explorer/content.js +1 -0
  57. package/app/templates/pods/explorer.js +1 -0
  58. package/app/templates/pods/index/pod.js +1 -0
  59. package/app/templates/pods/index.js +1 -0
  60. package/composer.json +10 -4
  61. package/extension.json +2 -2
  62. package/package.json +5 -5
  63. package/server/data/pods.json +328 -0
  64. package/server/src/Client/OpenIDConnectClient.php +2 -2
  65. package/server/src/Client/SolidClient.php +1 -1
  66. package/server/src/Http/Controllers/SolidController.php +57 -4
  67. package/server/src/LegacyClient/OIDCClient.php +1 -1
  68. package/server/src/LegacyClient/SolidClient.php +2 -1
  69. package/server/src/Support/Utils.php +38 -0
  70. package/server/src/routes.php +1 -0
@@ -0,0 +1,149 @@
1
+ import Controller from '@ember/controller';
2
+ import { action } from '@ember/object';
3
+ import { inject as service } from '@ember/service';
4
+ import { tracked } from '@glimmer/tracking';
5
+ import { task, timeout } from 'ember-concurrency';
6
+
7
+ export default class PodsExplorerController extends Controller {
8
+ @service hostRouter;
9
+ @service fetch;
10
+ @service notifications;
11
+ @service explorerState;
12
+ @service modalsManager;
13
+ @service crud;
14
+ @tracked cursor = '';
15
+ @tracked pod = '';
16
+ @tracked query = '';
17
+ queryParams = ['cursor', 'pod', 'query'];
18
+ columns = [
19
+ {
20
+ label: 'Name',
21
+ valuePath: 'name',
22
+ width: '75%',
23
+ cellComponent: 'table/cell/pod-content-name',
24
+ onClick: this.viewContents,
25
+ },
26
+ {
27
+ label: 'Type',
28
+ valuePath: 'type',
29
+ cellClassNames: 'capitalize',
30
+ width: '5%',
31
+ },
32
+ {
33
+ label: 'Size',
34
+ valuePath: 'size',
35
+ width: '5%',
36
+ },
37
+ {
38
+ label: 'Created At',
39
+ valuePath: 'created_at',
40
+ width: '15%',
41
+ },
42
+ {
43
+ label: '',
44
+ cellComponent: 'table/cell/pod-content-actions',
45
+ ddButtonText: false,
46
+ ddButtonIcon: 'ellipsis-h',
47
+ ddButtonIconPrefix: 'fas',
48
+ ddMenuLabel: 'Actions',
49
+ cellClassNames: 'overflow-visible',
50
+ wrapperClass: 'flex items-center justify-end mx-2',
51
+ width: '10%',
52
+ actions: (content) => {
53
+ return [
54
+ {
55
+ label: content.type === 'folder' ? 'Browse Folder' : 'View Contents',
56
+ fn: this.viewContents,
57
+ },
58
+ {
59
+ separator: true,
60
+ },
61
+ {
62
+ label: 'Delete',
63
+ fn: this.deleteSomething,
64
+ },
65
+ ];
66
+ },
67
+ sortable: false,
68
+ filterable: false,
69
+ resizable: false,
70
+ searchable: false,
71
+ },
72
+ ];
73
+
74
+ @action reload() {
75
+ this.hostRouter.refresh();
76
+ }
77
+
78
+ @action back() {
79
+ if (typeof this.cursor === 'string' && this.cursor.length && this.cursor !== this.model.id) {
80
+ const current = this.reverseCursor();
81
+ return this.hostRouter.transitionTo('console.solid-protocol.pods.explorer', current, { queryParams: { cursor: this.cursor, pod: this.pod } });
82
+ }
83
+
84
+ this.hostRouter.transitionTo('console.solid-protocol.pods.index');
85
+ }
86
+
87
+ @action viewContents(content) {
88
+ if (content.type === 'folder') {
89
+ return this.hostRouter.transitionTo('console.solid-protocol.pods.explorer', content, { queryParams: { cursor: this.trackCursor(content), pod: this.pod } });
90
+ }
91
+
92
+ if (content.type === 'file') {
93
+ return this.hostRouter.transitionTo('console.solid-protocol.pods.explorer.content', content);
94
+ }
95
+
96
+ return this.hostRouter.transitionTo('console.solid-protocol.pods.explorer', this.pod, { queryParams: { cursor: this.trackCursor(content), pod: this.pod } });
97
+ }
98
+
99
+ @action deleteSomething() {
100
+ this.modalsManager.confirm({
101
+ title: 'Are you sure you want to delete this content?',
102
+ body: 'Deleting this Content will remove this content from this pod. This is irreversible!',
103
+ acceptButtonText: 'Delete Forever',
104
+ confirm: () => {},
105
+ });
106
+ }
107
+
108
+ @action deleteSelected() {
109
+ const selected = this.table.selectedRows;
110
+
111
+ this.crud.bulkDelete(selected, {
112
+ modelNamePath: 'name',
113
+ acceptButtonText: 'Delete All',
114
+ onSuccess: () => {
115
+ return this.hostRouter.refresh();
116
+ },
117
+ });
118
+ }
119
+
120
+ trackCursor(content) {
121
+ if (typeof this.cursor === 'string' && this.cursor.includes(content.id)) {
122
+ const segments = this.cursor.split(':');
123
+ const currentIndex = segments.findIndex((segment) => segment === content.id);
124
+
125
+ if (currentIndex > -1) {
126
+ const retainedSegments = segments.slice(0, currentIndex + 1);
127
+ this.cursor = retainedSegments.join(':');
128
+ return this.cursor;
129
+ }
130
+ }
131
+
132
+ this.cursor = this.cursor ? `${this.cursor}:${content.id}` : content.id;
133
+ return this.cursor;
134
+ }
135
+
136
+ reverseCursor() {
137
+ const segments = this.cursor.split(':');
138
+ segments.pop();
139
+ const current = segments[segments.length - 1];
140
+ this.cursor = segments.join(':');
141
+ return current;
142
+ }
143
+
144
+ @task({ restartable: true }) *search(event) {
145
+ yield timeout(300);
146
+ const query = typeof event.target.value === 'string' ? event.target.value : '';
147
+ this.hostRouter.transitionTo('console.solid-protocol.pods.explorer', this.model.id, { queryParams: { cursor: this.cursor, query } });
148
+ }
149
+ }
@@ -0,0 +1,12 @@
1
+ import Controller from '@ember/controller';
2
+ import { action } from '@ember/object';
3
+
4
+ export default class PodsIndexPodController extends Controller {
5
+ @action setOverlayContext(overlayContextApi) {
6
+ this.overlayContextApi = overlayContextApi;
7
+ }
8
+
9
+ @action onPressClose() {
10
+ window.history.back();
11
+ }
12
+ }
@@ -0,0 +1,137 @@
1
+ import Controller from '@ember/controller';
2
+ import { action } from '@ember/object';
3
+ import { inject as service } from '@ember/service';
4
+ import { tracked } from '@glimmer/tracking';
5
+ import { task, timeout } from 'ember-concurrency';
6
+
7
+ export default class PodsIndexController extends Controller {
8
+ @service hostRouter;
9
+ @service notifications;
10
+ @service filters;
11
+ @service modalsManager;
12
+ @service crud;
13
+ @tracked query = '';
14
+
15
+ columns = [
16
+ {
17
+ label: 'Pod',
18
+ valuePath: 'name',
19
+ width: '80%',
20
+ cellComponent: 'table/cell/anchor',
21
+ onClick: this.explorePod,
22
+ },
23
+ {
24
+ label: 'Size',
25
+ valuePath: 'size',
26
+ width: '5%',
27
+ },
28
+ {
29
+ label: 'Created At',
30
+ valuePath: 'created_at',
31
+ width: '15%',
32
+ },
33
+ {
34
+ label: '',
35
+ cellComponent: 'table/cell/dropdown',
36
+ ddButtonText: false,
37
+ ddButtonIcon: 'ellipsis-h',
38
+ ddButtonIconPrefix: 'fas',
39
+ ddMenuLabel: 'Pod Actions',
40
+ cellClassNames: 'overflow-visible',
41
+ wrapperClass: 'flex items-center justify-end mx-2',
42
+ width: '10%',
43
+ actions: [
44
+ {
45
+ label: 'Browse',
46
+ fn: this.openPod,
47
+ },
48
+ {
49
+ label: 'Backup',
50
+ fn: this.backupPod,
51
+ },
52
+ {
53
+ label: 'Re-sync',
54
+ fn: this.resyncPod,
55
+ },
56
+ {
57
+ separator: true,
58
+ },
59
+ {
60
+ label: 'Delete',
61
+ fn: this.deletePod,
62
+ },
63
+ ],
64
+ sortable: false,
65
+ filterable: false,
66
+ resizable: false,
67
+ searchable: false,
68
+ },
69
+ ];
70
+
71
+ @action reload() {
72
+ this.hostRouter.refresh();
73
+ }
74
+
75
+ @action openPod(pod) {
76
+ this.hostRouter.transitionTo('console.solid-protocol.pods.index.pod', pod);
77
+ }
78
+
79
+ @action explorePod(pod) {
80
+ this.hostRouter.transitionTo('console.solid-protocol.pods.explorer', pod, { queryParams: { cursor: pod.id, pod: pod.id } });
81
+ }
82
+
83
+ @action createPod() {
84
+ this.modalsManager.show('modals/create-pod', {
85
+ title: 'Create a new Pod',
86
+ acceptButtonText: 'Create Pod',
87
+ pod: {
88
+ name: null,
89
+ },
90
+ confirm: () => {},
91
+ });
92
+ }
93
+
94
+ @action backupPod() {
95
+ this.modalsManager.confirm({
96
+ title: 'Are you sure you want to create a backup?',
97
+ body: 'Running a backup will create a duplicate Pod with the same contents.',
98
+ acceptButtonText: 'Start Backup',
99
+ confirm: () => {},
100
+ });
101
+ }
102
+
103
+ @action resyncPod() {
104
+ this.modalsManager.confirm({
105
+ title: 'Are you sure you want to re-sync?',
106
+ body: 'Running a re-sync will update all data from Fleetbase to this pod, overwriting the current contents with the latest.',
107
+ acceptButtonText: 'Start Sync',
108
+ confirm: () => {},
109
+ });
110
+ }
111
+
112
+ @action deletePod() {
113
+ this.modalsManager.confirm({
114
+ title: 'Are you sure you want to delete this Pod?',
115
+ body: "Deleting this Pod will destroy this pod and all it's contents. This is irreversible!",
116
+ acceptButtonText: 'Delete Forever',
117
+ confirm: () => {},
118
+ });
119
+ }
120
+
121
+ @action deleteSelectedPods() {
122
+ const selected = this.table.selectedRows;
123
+
124
+ this.crud.bulkDelete(selected, {
125
+ modelNamePath: 'name',
126
+ acceptButtonText: 'Delete All',
127
+ onSuccess: () => {
128
+ return this.hostRouter.refresh();
129
+ },
130
+ });
131
+ }
132
+
133
+ @task({ restartable: true }) *search(event) {
134
+ yield timeout(300);
135
+ this.query = typeof event.target.value === 'string' ? event.target.value : '';
136
+ }
137
+ }
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class AccountRoute extends Route {}
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class HomeRoute extends Route {}
@@ -0,0 +1,10 @@
1
+ import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+
4
+ export default class PodsExplorerContentRoute extends Route {
5
+ @service fetch;
6
+
7
+ model({ slug }) {
8
+ return this.fetch.get('pods', { slug }, { namespace: 'solid/int/v1' });
9
+ }
10
+ }
@@ -0,0 +1,44 @@
1
+ import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+ import { action } from '@ember/object';
4
+
5
+ export default class PodsExplorerRoute extends Route {
6
+ @service fetch;
7
+ @service explorerState;
8
+
9
+ queryParmas = {
10
+ query: {
11
+ refreshModel: true,
12
+ },
13
+ pod: {
14
+ refreshModel: false,
15
+ },
16
+ cursor: {
17
+ refreshModel: false,
18
+ },
19
+ };
20
+
21
+ @action willTransition(transition) {
22
+ const pod = transition.to.queryParams.pod;
23
+ const cursor = transition.to.queryParams.cursor;
24
+ if (pod && cursor) {
25
+ this.explorerState.trackWithCursor(pod, cursor);
26
+ }
27
+ }
28
+
29
+ beforeModel(transition) {
30
+ const pod = transition.to.queryParams.pod;
31
+ const cursor = transition.to.queryParams.cursor;
32
+ if (pod && cursor) {
33
+ this.explorerState.trackWithCursor(pod, cursor);
34
+ }
35
+ }
36
+
37
+ model({ id, query }) {
38
+ return this.fetch.get('pods', { id, query }, { namespace: 'solid/int/v1' });
39
+ }
40
+
41
+ afterModel(model, transition) {
42
+ this.explorerState.track(transition.to.queryParams.pod, model);
43
+ }
44
+ }
@@ -0,0 +1,3 @@
1
+ import Route from '@ember/routing/route';
2
+
3
+ export default class PodsIndexPodRoute extends Route {}
@@ -0,0 +1,21 @@
1
+ import Route from '@ember/routing/route';
2
+ import { inject as service } from '@ember/service';
3
+
4
+ export default class PodsIndexRoute extends Route {
5
+ @service fetch;
6
+ @service appCache;
7
+
8
+ queryParams = {
9
+ query: {
10
+ refreshModel: true,
11
+ },
12
+ };
13
+
14
+ model(params) {
15
+ return this.fetch.get('pods', params, { namespace: 'solid/int/v1' });
16
+ }
17
+
18
+ afterModel(model) {
19
+ this.appCache.set('solid:pods', model);
20
+ }
21
+ }
package/addon/routes.js CHANGED
@@ -1,3 +1,14 @@
1
1
  import buildRoutes from 'ember-engines/routes';
2
2
 
3
- export default buildRoutes(function () {});
3
+ export default buildRoutes(function () {
4
+ this.route('home', { path: '/' });
5
+ this.route('account');
6
+ this.route('pods', function () {
7
+ this.route('explorer', { path: '/explorer/:id' }, function () {
8
+ this.route('content', { path: '/~/:slug' });
9
+ });
10
+ this.route('index', { path: '/' }, function () {
11
+ this.route('pod', { path: '/pod/:slug' });
12
+ });
13
+ });
14
+ });
@@ -0,0 +1,101 @@
1
+ import Service from '@ember/service';
2
+ import Evented from '@ember/object/evented';
3
+ import { inject as service } from '@ember/service';
4
+ import { isArray } from '@ember/array';
5
+
6
+ export default class ExplorerStateService extends Service.extend(Evented) {
7
+ @service appCache;
8
+
9
+ trackWithCursor(id, cursor) {
10
+ const segments = typeof cursor === 'string' ? cursor.split(':') : [];
11
+ const state = this.get(id);
12
+ this.update(
13
+ id,
14
+ state.filter((content) => {
15
+ return segments.includes(content.id);
16
+ })
17
+ );
18
+ this.clean(id);
19
+ return this;
20
+ }
21
+
22
+ track(id, content) {
23
+ if (id === content.id) {
24
+ this.initialize(id, content);
25
+ } else {
26
+ this.push(id, content);
27
+ }
28
+
29
+ this.clean(id);
30
+ return this;
31
+ }
32
+
33
+ initialize(id, content) {
34
+ const state = this.get(id);
35
+ if (isArray(state) && state.length === 0) {
36
+ state.pushObject(content);
37
+ this.update(id, state);
38
+ }
39
+
40
+ return this;
41
+ }
42
+
43
+ push(id, content) {
44
+ const state = this.get(id);
45
+ if (isArray(state) && this.doesntHave(id, content)) {
46
+ state.pushObject(content);
47
+ this.update(id, state);
48
+ }
49
+
50
+ return this;
51
+ }
52
+
53
+ pop(id) {
54
+ const state = this.get(id);
55
+ if (isArray(state)) {
56
+ state.pop();
57
+ this.update(id, state);
58
+ }
59
+
60
+ return this;
61
+ }
62
+
63
+ has(id, content) {
64
+ const state = this.get(id);
65
+ return state.findIndex((_) => _.id === content.id) >= 0;
66
+ }
67
+
68
+ doesntHave(id, content) {
69
+ return !this.has(id, content);
70
+ }
71
+
72
+ get(id) {
73
+ return this.appCache.get(`${id}:explorer:state`, []);
74
+ }
75
+
76
+ update(id, state = []) {
77
+ this.appCache.set(`${id}:explorer:state`, state);
78
+ this.trigger('change', id, state);
79
+ return this;
80
+ }
81
+
82
+ clean(id) {
83
+ const state = this.get(id);
84
+ if (isArray(state)) {
85
+ const seenIds = new Set();
86
+ this.update(
87
+ id,
88
+ state.filter((_) => {
89
+ if (seenIds.has(_.id)) {
90
+ return false;
91
+ }
92
+
93
+ seenIds.add(_.id);
94
+ return true;
95
+ })
96
+ );
97
+ }
98
+
99
+ return this;
100
+ }
101
+ }
@@ -27,3 +27,49 @@ body[data-theme='dark'] .solid-fleetbase-home-container a:not([class*='text-']),
27
27
  .solid-fleetbase-home-container a:hover {
28
28
  opacity: 0.5;
29
29
  }
30
+
31
+ .pod-explorer-breadcrumb-container {
32
+ display: flex;
33
+ flex-direction: row;
34
+ align-items: center;
35
+ }
36
+
37
+ .pod-explorer-breadcrumb-container > .pod-explorer-breadcrumb:first-child {
38
+ border-top-left-radius: 0.75rem;
39
+ border-bottom-left-radius: 0.75rem;
40
+ }
41
+
42
+ .pod-explorer-breadcrumb-container > .pod-explorer-breadcrumb:last-child {
43
+ border-top-right-radius: 0.75rem;
44
+ border-bottom-right-radius: 0.75rem;
45
+ }
46
+
47
+ .pod-explorer-breadcrumb {
48
+ font-size: 0.85rem;
49
+ border: 1px #111827 solid;
50
+ padding: 0 0.75rem;
51
+ line-height: 1.75rem;
52
+ background-color: #1f2937;
53
+ color: #fff;
54
+ }
55
+
56
+ .pod-explorer-breadcrumb:hover {
57
+ opacity: 0.75;
58
+ }
59
+
60
+ .pod-explorer-breadcrumb.active-breadcrumb {
61
+ background-color: #2563eb;
62
+ color: #eff6ff;
63
+ }
64
+
65
+ body[data-theme='light'] .pod-explorer-breadcrumb {
66
+ border: 1px #e5e7eb solid;
67
+ background-color: #e5e7eb;
68
+ color: #1f2937;
69
+ }
70
+
71
+ body[data-theme='light'] .pod-explorer-breadcrumb.active-breadcrumb {
72
+ background-color: #3b82f6;
73
+ color: #eff6ff;
74
+ border-color: #2563eb;
75
+ }
@@ -0,0 +1,42 @@
1
+ <Layout::Section::Header @title="Your Account" />
2
+
3
+ <Layout::Section::Body class="overflow-y-scroll h-full">
4
+ <div class="container mx-auto h-screen">
5
+ <div class="max-w-3xl my-10 mx-auto">
6
+ <ContentPanel @title="Solid Identity" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
7
+ <form class="flex flex-col md:flex-row" {{on "submit" (perform this.saveProfile)}}>
8
+ <div class="w-32 flex flex-col justify-center mb-6 mr-6">
9
+ <Image src={{this.user.avatar_url}} @fallbackSrc={{config "defaultValues.userImage"}} alt={{this.user.name}} class="w-32 h-32 rounded-md" />
10
+ <FileUpload @name={{t "console.account.index.photos"}} @accept="image/*" @onFileAdded={{this.uploadNewPhoto}} @labelClass="flex flex-row items-center justify-center" as |queue|>
11
+ <a tabindex={{0}} class="flex items-center px-0 mt-2 text-xs no-underline truncate btn btn-sm btn-default" disabled={{queue.files.length}}>
12
+ {{#if queue.files.length}}
13
+ <div class="mr-1.5">
14
+ <Spinner />
15
+ </div>
16
+ <span>
17
+ {{t "common.uploading"}}
18
+ </span>
19
+ {{else}}
20
+ <FaIcon @icon="image" class="mr-1.5" />
21
+ <span>
22
+ {{t "console.account.index.upload-new"}}
23
+ </span>
24
+ {{/if}}
25
+ </a>
26
+ </FileUpload>
27
+ </div>
28
+ <div class="flex-1">
29
+ <div class="grid grid-cols-1 gap-2 text-xs dark:text-gray-100">
30
+ <InputGroup @name={{t "common.name"}} @value={{this.user.name}} />
31
+ <InputGroup @name={{t "common.email"}} @type="email" @value={{this.user.email}} />
32
+ </div>
33
+ <div class="mt-3 flex items-center justify-end">
34
+ <Button @buttonType="submit" @type="primary" @size="lg" @icon="save" @text={{t "common.save-button-text"}} @onClick={{perform this.saveProfile}} @isLoading={{not this.saveProfile.isIdle}} />
35
+ </div>
36
+ </div>
37
+ </form>
38
+ </ContentPanel>
39
+ </div>
40
+ </div>
41
+ <Spacer @height="500px" />
42
+ </Layout::Section::Body>
@@ -1,15 +1,20 @@
1
- <Layout::Section::Container class="solid-fleetbase-home">
2
- <Layout::Section::Header @title="Solid for Fleetbase" />
1
+ <EmberWormhole @to="sidebar-menu-items">
2
+ <Layout::Sidebar::Item @route="console.solid-protocol.home" @icon="home">Home</Layout::Sidebar::Item>
3
+ <Layout::Sidebar::Item @route="console.solid-protocol.pods" @icon="folder-tree">Pods</Layout::Sidebar::Item>
4
+ {{!-- <Layout::Sidebar::Panel @open={{true}} @title="Pods">
5
+ <Layout::Sidebar::Item @route="console.solid-protocol.pods" @icon="folder-tree">All</Layout::Sidebar::Item>
6
+ {{#each this.pods as |pod|}}
7
+ <LinkTo @route="pods.explorer" @model={{pod}} @query={{hash id=pod.id pod=pod.id}} class="next-nav-item">
8
+ <div class="next-nav-item-icon-container">
9
+ <FaIcon @icon="folder" @size="xs" />
10
+ </div>
11
+ <div class="truncate w-10/12 ">{{pod.name}}</div>
12
+ </LinkTo>
13
+ {{/each}}
14
+ </Layout::Sidebar::Panel> --}}
15
+ <Layout::Sidebar::Item @route="console.solid-protocol.account" @icon="user">Account</Layout::Sidebar::Item>
16
+ </EmberWormhole>
3
17
 
4
- <Layout::Section::Body class="solid-fleetbase-home-container">
5
- <h1>Welcome to Solid for Fleetbase</h1>
6
- <h2>Getting Started</h2>
7
- <div class="mt-2">
8
- <p>
9
- <a href="#" {{on "click" (perform this.authenticate)}}>Sign up for an account</a> to get started with your own Pod and WebID. Once you are logged in you can begin to manage your pods and sync data directly from Fleetbase to your Pods.
10
- </p>
11
- </div>
12
- {{!-- <Button @text="Click to Test" @icon="magic" @onClick={{perform this.getAccountIndex}} @wrapperClass="mt-4" /> --}}
13
- </Layout::Section::Body>
18
+ <Layout::Section::Container class="solid-fleetbase-home">
14
19
  {{outlet}}
15
20
  </Layout::Section::Container>
@@ -0,0 +1,11 @@
1
+ <Layout::Section::Header @title="Solid for Fleetbase" />
2
+ <Layout::Section::Body class="solid-fleetbase-home-container">
3
+ <h1>Welcome to Solid for Fleetbase</h1>
4
+ <h2>Getting Started</h2>
5
+ <div class="mt-2">
6
+ <p>
7
+ <a href="#" {{on "click" (perform this.authenticate)}}>Sign up for an account</a> to get started with your own Pod and WebID. Once you are logged in you can begin to manage your pods and sync data directly from Fleetbase to your Pods.
8
+ </p>
9
+ </div>
10
+ {{!-- <Button @text="Click to Test" @icon="magic" @onClick={{perform this.getAccountIndex}} @wrapperClass="mt-4" /> --}}
11
+ </Layout::Section::Body>
@@ -0,0 +1,19 @@
1
+ <Overlay @isOpen={{true}} @onLoad={{this.setOverlayContext}} @position="right" @noBackdrop={{true}} @fullHeight={{true}} @width="600px" @isResizable={{true}}>
2
+ <Overlay::Header @title={{@model.name}} @hideStatusDot={{true}} @titleWrapperClass="leading-5">
3
+ <div class="flex flex-1 justify-end">
4
+ <Button @type="default" @icon="times" @helpText={{t "common.close"}} @onClick={{this.onPressClose}} />
5
+ </div>
6
+ </Overlay::Header>
7
+
8
+ <Overlay::Body>
9
+ <div class="p-4 space-y-2">
10
+ <div>ID: {{@model.id}}</div>
11
+ <div>Name: {{@model.name}}</div>
12
+ <div>Size: {{@model.size}}</div>
13
+ <div class="mt-2 rounded-md border border-gray-700 p-3 bg-gray-800">
14
+ <div class="font-semibold">Contents:</div>
15
+ <div></div>
16
+ </div>
17
+ </div>
18
+ </Overlay::Body>
19
+ </Overlay>