diff --git a/KTUSAPS/ClientApp/package.json b/KTUSAPS/ClientApp/package.json index ec0ecfc..5f63105 100644 --- a/KTUSAPS/ClientApp/package.json +++ b/KTUSAPS/ClientApp/package.json @@ -13,6 +13,7 @@ "axios": "^0.25.0", "bootstrap": "^5.1.3", "bootstrap-icons": "^1.7.2", + "lodash": "^4.17.21", "vue": "^3.2.25", "vue-router": "^4.0.12", "vuex": "^4.0.2" diff --git a/KTUSAPS/ClientApp/src/App.vue b/KTUSAPS/ClientApp/src/App.vue index 07625a1..5161db5 100644 --- a/KTUSAPS/ClientApp/src/App.vue +++ b/KTUSAPS/ClientApp/src/App.vue @@ -1,6 +1,11 @@ diff --git a/KTUSAPS/ClientApp/src/assets/main.scss b/KTUSAPS/ClientApp/src/assets/main.scss index 281d97b..2d084eb 100644 --- a/KTUSAPS/ClientApp/src/assets/main.scss +++ b/KTUSAPS/ClientApp/src/assets/main.scss @@ -7,17 +7,11 @@ /* Enter and leave animations can use different */ /* durations and timing functions. */ .slide-fade-enter-active { - transition: all 0.3s ease-out; + transition: all 0.15s ease-out; } .slide-fade-leave-active { - transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1); -} - -.slide-fade-leave-active, -.slide-fade-enter-active { - position: relative; - top: 0; + transition: all 0.15s cubic-bezier(1, 0.5, 0.8, 1); } .slide-fade-enter-from, @@ -31,3 +25,23 @@ transform: translateX(0px); opacity: 1; } + +.fade-enter-active { + transition: all 0.3s ease-out; +} + +.fade-leave-active { + transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1); +} + +.fade-enter-from, +.fade-leave-to { + opacity: 0; + transform: scale(0); +} + +.fade-enter-to, +.fade-leave-from { + opacity: 1; + transform: scale(1); +} diff --git a/KTUSAPS/ClientApp/src/components/AdminMenu.vue b/KTUSAPS/ClientApp/src/components/AdminMenu.vue new file mode 100644 index 0000000..f4ee5b9 --- /dev/null +++ b/KTUSAPS/ClientApp/src/components/AdminMenu.vue @@ -0,0 +1,58 @@ + + + diff --git a/KTUSAPS/ClientApp/src/components/Alerter.vue b/KTUSAPS/ClientApp/src/components/Alerter.vue new file mode 100644 index 0000000..b3f7ffd --- /dev/null +++ b/KTUSAPS/ClientApp/src/components/Alerter.vue @@ -0,0 +1,67 @@ + + + diff --git a/KTUSAPS/ClientApp/src/components/ConfirmAlert.vue b/KTUSAPS/ClientApp/src/components/ConfirmAlert.vue new file mode 100644 index 0000000..5a09c44 --- /dev/null +++ b/KTUSAPS/ClientApp/src/components/ConfirmAlert.vue @@ -0,0 +1,98 @@ + + + diff --git a/KTUSAPS/ClientApp/src/components/NavMenu.vue b/KTUSAPS/ClientApp/src/components/NavMenu.vue index d9df1ed..91335b7 100644 --- a/KTUSAPS/ClientApp/src/components/NavMenu.vue +++ b/KTUSAPS/ClientApp/src/components/NavMenu.vue @@ -1,73 +1,68 @@ diff --git a/KTUSAPS/ClientApp/src/components/forms/IssueTypeForm.vue b/KTUSAPS/ClientApp/src/components/forms/IssueTypeForm.vue new file mode 100644 index 0000000..d203197 --- /dev/null +++ b/KTUSAPS/ClientApp/src/components/forms/IssueTypeForm.vue @@ -0,0 +1,27 @@ + + + diff --git a/KTUSAPS/ClientApp/src/components/forms/formHelpers.js b/KTUSAPS/ClientApp/src/components/forms/formHelpers.js new file mode 100644 index 0000000..7c1c67b --- /dev/null +++ b/KTUSAPS/ClientApp/src/components/forms/formHelpers.js @@ -0,0 +1,27 @@ +export function autoComputed(propName, defaultValue) { + return { + get() { + return this.modelValue[propName] || defaultValue + }, + set(value) { + this.$emit('update:modelValue', { + ...this.modelValue, + [propName]: value, + }) + }, + } +} + +export function mapModel(props) { + const computedValues = {} + if (Array.isArray(props)) { + props.forEach((propName) => { + computedValues[propName] = autoComputed(propName, '') + }) + } else { + Object.entries(props).forEach(([propName, defaultValue]) => { + computedValues[propName] = autoComputed(propName, defaultValue) + }) + } + return computedValues +} diff --git a/KTUSAPS/ClientApp/src/main.js b/KTUSAPS/ClientApp/src/main.js index 79e5c95..00e3ff4 100644 --- a/KTUSAPS/ClientApp/src/main.js +++ b/KTUSAPS/ClientApp/src/main.js @@ -11,4 +11,4 @@ const app = createApp(App) app.use(router) app.use(store) -app.mount('#app') \ No newline at end of file +app.mount('#app') diff --git a/KTUSAPS/ClientApp/src/msal.js b/KTUSAPS/ClientApp/src/msal.js index 986fb93..acff5a0 100644 --- a/KTUSAPS/ClientApp/src/msal.js +++ b/KTUSAPS/ClientApp/src/msal.js @@ -21,6 +21,7 @@ const msalState = { displayName: null, debugFullTokenResponse: null, + msalRefreshTimer: null, } async function initializeMSAL() { @@ -35,6 +36,7 @@ async function initializeMSAL() { redirectUri: window.location.protocol + '//' + window.location.host + '/', }, } + msalState.msalRefreshTimer = setInterval(__refreshToken, 10 * 60 * 1000) msalState.msal = new msal.PublicClientApplication(msalConfig) @@ -70,6 +72,22 @@ export function LogoutMsal() { msalState.msal.logout() } +async function __refreshToken() { + if (!msalState.isLoggedIn) return + msalState.debugFullTokenResponse = await msalState.msal + .acquireTokenSilent({ scopes: RequestedScopes }) + .catch((error) => { + if (error instanceof msal.InteractionRequiredAuthError) { + // fallback to interaction when silent call fails + return msalState.msal.acquireTokenRedirect({ + scopes: RequestedScopes, + }) + } + }) + __responseObjectToMsalState() + __stateChanged() +} + async function __handleResponse(response) { if (response !== null) { if (__isAccountAceptable(response.account)) { @@ -82,7 +100,7 @@ async function __handleResponse(response) { msalState.msal .getAllAccounts() .filter(__isAccountAceptable) - .forEach(account => { + .forEach((account) => { msalState.msal.setActiveAccount(account) }) @@ -90,7 +108,7 @@ async function __handleResponse(response) { if (account != null) { msalState.debugFullTokenResponse = await msalState.msal .acquireTokenSilent({ scopes: RequestedScopes }) - .catch(error => { + .catch((error) => { if (error instanceof msal.InteractionRequiredAuthError) { // fallback to interaction when silent call fails return msalState.msal.acquireTokenRedirect({ @@ -118,7 +136,7 @@ function __isAccountAceptable(account) { } function __stateChanged() { - msalState.stateChangeCallbacks.forEach(cb => cb()) + msalState.stateChangeCallbacks.forEach((cb) => cb()) } async function __loadAuthParameters() { diff --git a/KTUSAPS/ClientApp/src/pages/Issues.vue b/KTUSAPS/ClientApp/src/pages/Issues.vue index f3f0ce1..e1ad0b6 100644 --- a/KTUSAPS/ClientApp/src/pages/Issues.vue +++ b/KTUSAPS/ClientApp/src/pages/Issues.vue @@ -66,6 +66,7 @@ export default { this.error = null this.ok = null try { + await this.$root.deleteConfirmation() await authAxios.delete(`/api/Issues/${id}`) this.ok = 'Sėkmingai ištrintą' await this.fetchData() diff --git a/KTUSAPS/ClientApp/src/pages/NewFeedback.vue b/KTUSAPS/ClientApp/src/pages/NewFeedback.vue index f5f34c2..d74afe9 100644 --- a/KTUSAPS/ClientApp/src/pages/NewFeedback.vue +++ b/KTUSAPS/ClientApp/src/pages/NewFeedback.vue @@ -24,28 +24,7 @@
-
- - -
-
- - -
+ @@ -56,8 +35,12 @@ diff --git a/KTUSAPS/ClientApp/src/pages/admin/IssueTypeNew.vue b/KTUSAPS/ClientApp/src/pages/admin/IssueTypeNew.vue new file mode 100644 index 0000000..6653b04 --- /dev/null +++ b/KTUSAPS/ClientApp/src/pages/admin/IssueTypeNew.vue @@ -0,0 +1,54 @@ + + + diff --git a/KTUSAPS/ClientApp/src/pages/admin/IssueTypes.vue b/KTUSAPS/ClientApp/src/pages/admin/IssueTypes.vue new file mode 100644 index 0000000..b29394d --- /dev/null +++ b/KTUSAPS/ClientApp/src/pages/admin/IssueTypes.vue @@ -0,0 +1,57 @@ + + + diff --git a/KTUSAPS/ClientApp/src/router/admin.js b/KTUSAPS/ClientApp/src/router/admin.js new file mode 100644 index 0000000..56fcc42 --- /dev/null +++ b/KTUSAPS/ClientApp/src/router/admin.js @@ -0,0 +1,28 @@ +import IssueTypes from '@/pages/admin/IssueTypes.vue' +import IssueTypeNew from '@/pages/admin/IssueTypeNew.vue' +import IssueTypeEdit from '@/pages/admin/IssueTypeEdit.vue' +import Admin from '@/pages/admin/Admin.vue' + +export default [ + { + path: '/admin', + component: Admin, + children: [ + { + path: 'issuetypes', + name: 'AdminIssueTypes', + component: IssueTypes, + }, + { + path: 'issuetypes/new', + name: 'AdminIssueTypeNew', + component: IssueTypeNew, + }, + { + path: 'issuetypes/:id/edit', + name: 'AdminIssueTypeEdit', + component: IssueTypeEdit, + }, + ], + }, +] diff --git a/KTUSAPS/ClientApp/src/router/index.js b/KTUSAPS/ClientApp/src/router/index.js index d7f3b23..910a01d 100644 --- a/KTUSAPS/ClientApp/src/router/index.js +++ b/KTUSAPS/ClientApp/src/router/index.js @@ -6,6 +6,7 @@ import Feedbacks from '@/pages/Feedbacks.vue' import Issues from '@/pages/Issues.vue' import NewProblem from '@/pages/NewProblem.vue' import NewFeedback from '@/pages/NewFeedback.vue' +import AdminRoutes from './admin' const routes = [ { @@ -43,6 +44,7 @@ const routes = [ name: 'IssueNewFeedback', component: NewFeedback, }, + ...AdminRoutes, ] const router = createRouter({ diff --git a/KTUSAPS/ClientApp/yarn.lock b/KTUSAPS/ClientApp/yarn.lock index b7268d8..b5387ca 100644 --- a/KTUSAPS/ClientApp/yarn.lock +++ b/KTUSAPS/ClientApp/yarn.lock @@ -375,6 +375,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + magic-string@^0.25.7: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"