diff --git a/dashboard/public/js/index.js b/dashboard/public/js/index.js index c5b323473..ddaf5f47a 100644 --- a/dashboard/public/js/index.js +++ b/dashboard/public/js/index.js @@ -50,8 +50,8 @@ app.config(['$routeProvider', function ($routeProvider) { controller: 'UsersController', templateUrl: 'views/users.html?' + window.VITE_CACHE_ID }).when('/user-directory', { - controller: 'UserSettingsController', - templateUrl: 'views/user-directory.html?' + window.VITE_CACHE_ID + // controller: 'UserSettingsController', + // templateUrl: 'views/user-directory.html?' + window.VITE_CACHE_ID }).when('/app/:appId/:view?', { controller: 'AppController', templateUrl: 'views/app.html?' + window.VITE_CACHE_ID diff --git a/dashboard/src/components/ExposedLdap.vue b/dashboard/src/components/ExposedLdap.vue new file mode 100644 index 000000000..8985b6b6e --- /dev/null +++ b/dashboard/src/components/ExposedLdap.vue @@ -0,0 +1,112 @@ + + + diff --git a/dashboard/src/components/ExternalLdap.vue b/dashboard/src/components/ExternalLdap.vue new file mode 100644 index 000000000..dec51f7c7 --- /dev/null +++ b/dashboard/src/components/ExternalLdap.vue @@ -0,0 +1,410 @@ + + + + + diff --git a/dashboard/src/components/Index.vue b/dashboard/src/components/Index.vue index 1e328422e..82b87529a 100644 --- a/dashboard/src/components/Index.vue +++ b/dashboard/src/components/Index.vue @@ -6,6 +6,7 @@ import AppsView from './AppsView.vue'; import AppstoreView from './AppstoreView.vue'; import ProfileView from './ProfileView.vue'; import SupportView from './SupportView.vue'; +import UserDirectoryView from './UserDirectoryView.vue'; import VolumesView from './VolumesView.vue'; import ProfileModel from '../models/ProfileModel.js'; @@ -17,6 +18,7 @@ const VIEWS = { APPSTORE: 'appstore', PROFILE: 'profile', SUPPORT: 'support', + USER_DIRECTORY: 'user-directory', VOLUMES: 'volumes', }; @@ -28,6 +30,7 @@ export default { Notification, ProfileView, SupportView, + UserDirectoryView, VolumesView, }, data() { @@ -61,6 +64,8 @@ export default { that.view = VIEWS.PROFILE; } else if (view === VIEWS.SUPPORT) { that.view = VIEWS.SUPPORT; + } else if (view === VIEWS.USER_DIRECTORY) { + that.view = VIEWS.USER_DIRECTORY; } else if (view === VIEWS.VOLUMES) { that.view = VIEWS.VOLUMES; } else { @@ -85,6 +90,7 @@ export default { + diff --git a/dashboard/src/components/UserDirectoryView.vue b/dashboard/src/components/UserDirectoryView.vue new file mode 100644 index 000000000..92976259e --- /dev/null +++ b/dashboard/src/components/UserDirectoryView.vue @@ -0,0 +1,60 @@ + + + diff --git a/dashboard/src/models/TasksModel.js b/dashboard/src/models/TasksModel.js new file mode 100644 index 000000000..6a16a3b06 --- /dev/null +++ b/dashboard/src/models/TasksModel.js @@ -0,0 +1,44 @@ + +import { fetcher } from 'pankow'; + +function create(origin, accessToken) { + return { + async getLatestByType(type) { + let error, result; + try { + result = await fetcher.get(`${origin}/api/v1/tasks`, { type, page: 1, per_page: 1, access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null, result.body.tasks.length ? result.body.tasks[0] : null]; + }, + async getByType(type) { + let error, result; + try { + result = await fetcher.get(`${origin}/api/v1/tasks`, { type, access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null, result.body.tasks]; + }, + async get(id) { + let error, result; + try { + result = await fetcher.get(`${origin}/api/v1/tasks/${id}`, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null, result.body]; + }, + }; +} + +export default { + create, +}; diff --git a/dashboard/src/models/UserDirectoryModel.js b/dashboard/src/models/UserDirectoryModel.js new file mode 100644 index 000000000..e7b7f41f9 --- /dev/null +++ b/dashboard/src/models/UserDirectoryModel.js @@ -0,0 +1,94 @@ + +import { fetcher } from 'pankow'; + +function create(origin, accessToken) { + return { + async getGlobalProfileConfig() { + let error, result; + try { + result = await fetcher.get(`${origin}/api/v1/user_directory/profile_config`, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null, result.body]; + }, + async setGlobalProfileConfig(config) { + let error, result; + try { + result = await fetcher.post(`${origin}/api/v1/user_directory/profile_config`, config, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null]; + }, + async getExternalLdapConfig() { + let error, result; + try { + result = await fetcher.get(`${origin}/api/v1/external_ldap/config`, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null, result.body]; + }, + async setExternalLdapConfig(config) { + let error, result; + try { + result = await fetcher.post(`${origin}/api/v1/external_ldap/config`, config, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null]; + }, + async startExternalLdapSync() { + let error, result; + try { + result = await fetcher.post(`${origin}/api/v1/external_ldap/sync`, {}, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 202) return [error || result]; + return [null, result.body.taskId]; + }, + async getExposedLdapConfig() { + let error, result; + try { + result = await fetcher.get(`${origin}/api/v1/directory_server/config`, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 200) return [error || result]; + return [null, result.body]; + }, + async setExposedLdapConfig(config) { + const data = { + enabled: config.enabled, + allowlist: config.allowlist, + secret: config.secret, + }; + + let error, result; + try { + result = await fetcher.post(`${origin}/api/v1/directory_server/config`, data, { access_token: accessToken }); + } catch (e) { + error = e; + } + + if (error || result.status !== 202) return [error || result]; + return [null]; + }, + }; +} + +export default { + create, +}; diff --git a/dashboard/src/style.css b/dashboard/src/style.css index 7f10afb34..71c388873 100644 --- a/dashboard/src/style.css +++ b/dashboard/src/style.css @@ -94,3 +94,37 @@ footer > .p { tr:hover .table-actions { visibility: visible; } + +/* status classes for circle indicators */ +.status-active { + color: #27CE65; +} + +.status-inactive { + color: #7c7c7c; +} + +.status-starting { + color: #f0ad4e; +} + +.status-error { + color: #ec534f; +} + +/* generic test modifiers */ +.text-success { + color: #5CB85C; +} + +.text-warning { + color: #8a6d3b; +} + +.text-bold { + font-weight: bold; +} + +.text-small { + font-size: 12px; +}