@fdm-monster/client-next 0.0.1 → 0.0.3
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.
- package/.yarn/install-state.gz +0 -0
- package/RELEASE_NOTES.MD +28 -1
- package/dist/assets/MaterialIcons-Regular-BjXOXp5c.eot +0 -0
- package/dist/assets/MaterialIcons-Regular-DEUTIz1o.ttf +0 -0
- package/dist/assets/MaterialIcons-Regular-DOtZ65Va.woff2 +0 -0
- package/dist/assets/MaterialIcons-Regular-FsbMSDLx.woff +0 -0
- package/dist/assets/index-CHzfWKPO.css +5 -0
- package/dist/assets/index-WVqTlgq7.js +90 -0
- package/dist/assets/index-WVqTlgq7.js.map +1 -0
- package/dist/favicon.ico +0 -0
- package/dist/img/DavidZwart.jpg +0 -0
- package/dist/img/OIG.JYDC2RaWdz7g9.jpg +0 -0
- package/dist/img/OIG.jpg +0 -0
- package/dist/img/icons/android-chrome-256x256.png +0 -0
- package/dist/img/icons/android-chrome-384x384.png +0 -0
- package/dist/img/icons/android-chrome-512x512.png +0 -0
- package/dist/img/icons/favicon.svg +1 -0
- package/dist/img/logo.png +0 -0
- package/dist/img/logo.svg +1 -0
- package/dist/img/manifest.webmanifest +33 -0
- package/dist/img/octoprint-tentacle.svg +144 -0
- package/dist/img/thumbail_unknown.jpg +0 -0
- package/dist/img/vbanner.jpg +0 -0
- package/dist/index.html +24 -0
- package/dist/robots.txt +2 -0
- package/package.json +1 -1
- package/.all-contributorsrc +0 -57
- package/.editorconfig +0 -5
- package/.eslintrc.js +0 -126
- package/.github/FUNDING.yml +0 -3
- package/.github/workflows/release-client.yml +0 -94
- package/.github/workflows/vue-publish.yml +0 -26
- package/.prettierignore +0 -15
- package/.whitesource +0 -12
- package/renovate.json +0 -30
- package/src/App.vue +0 -60
- package/src/AppLoader.vue +0 -383
- package/src/assets/adjectives.json +0 -1468
- package/src/assets/logo.svg +0 -6
- package/src/assets/nouns.json +0 -4309
- package/src/auto-imports.d.ts +0 -139
- package/src/backend/app.service.ts +0 -39
- package/src/backend/auth.service.ts +0 -56
- package/src/backend/base.service.ts +0 -57
- package/src/backend/batch.service.ts +0 -37
- package/src/backend/camera-stream.service.ts +0 -33
- package/src/backend/custom-gcode.service.ts +0 -11
- package/src/backend/dto/octoprint-settings.dto.ts +0 -168
- package/src/backend/first-time-setup.service.ts +0 -17
- package/src/backend/floor.service.ts +0 -84
- package/src/backend/index.ts +0 -4
- package/src/backend/print-completions.service.ts +0 -11
- package/src/backend/printer-file.service.ts +0 -91
- package/src/backend/printer-group.service.ts +0 -62
- package/src/backend/printer-job.service.ts +0 -20
- package/src/backend/printer-settings.service.ts +0 -28
- package/src/backend/printers.service.ts +0 -136
- package/src/backend/server-private.service.ts +0 -55
- package/src/backend/server.api.ts +0 -132
- package/src/backend/settings.service.ts +0 -85
- package/src/backend/user.service.ts +0 -51
- package/src/components/AboutHelp/AboutView.vue +0 -164
- package/src/components/CameraGrid/CameraGridView.vue +0 -111
- package/src/components/FirstTimeSetup/FirstTimeSetupView.vue +0 -354
- package/src/components/Generic/Actions/PrinterConnectionAction.vue +0 -56
- package/src/components/Generic/Actions/PrinterCreateAction.vue +0 -22
- package/src/components/Generic/Actions/PrinterDeleteAction.vue +0 -29
- package/src/components/Generic/Actions/PrinterQuickStopAction.vue +0 -35
- package/src/components/Generic/Actions/PrinterSettingsAction.vue +0 -35
- package/src/components/Generic/Actions/PrinterUrlAction.vue +0 -24
- package/src/components/Generic/Actions/RefreshFilesAction.vue +0 -50
- package/src/components/Generic/Actions/SyncPrinterNameAction.vue +0 -36
- package/src/components/Generic/Dialogs/AddOrUpdateCameraStreamDialog.vue +0 -131
- package/src/components/Generic/Dialogs/AddOrUpdateFloorDialog.vue +0 -141
- package/src/components/Generic/Dialogs/AddOrUpdatePrinterDialog.vue +0 -303
- package/src/components/Generic/Dialogs/BaseDialog.vue +0 -81
- package/src/components/Generic/Dialogs/BatchJsonCreateDialog.vue +0 -109
- package/src/components/Generic/Dialogs/BatchReprintDialog.vue +0 -190
- package/src/components/Generic/Dialogs/PrinterChecksPanel.vue +0 -37
- package/src/components/Generic/Dialogs/PrinterControlDialog.vue +0 -202
- package/src/components/Generic/Dialogs/PrinterMaintenanceDialog.vue +0 -130
- package/src/components/Generic/Dialogs/YamlImportExportDialog.vue +0 -186
- package/src/components/Generic/Dialogs/dialog.constants.ts +0 -19
- package/src/components/Generic/FileExplorerSideNav.vue +0 -734
- package/src/components/Generic/Loaders/GridLoader.vue +0 -68
- package/src/components/Generic/NavigationDrawer.vue +0 -69
- package/src/components/Generic/PrintJobsMenu.vue +0 -148
- package/src/components/Generic/Snackbars/AppErrorSnackbar.vue +0 -64
- package/src/components/Generic/Snackbars/AppInfoSnackbar.vue +0 -63
- package/src/components/Generic/Snackbars/AppProgressSnackbar.vue +0 -158
- package/src/components/Generic/Vuetify/TooltipButton.vue +0 -47
- package/src/components/HelpOverlay/HelpOverlay.vue +0 -57
- package/src/components/Login/LoginForm.vue +0 -206
- package/src/components/Login/LoginView.spec.ts +0 -64
- package/src/components/Login/LoginView.vue +0 -65
- package/src/components/Login/Logo.vue +0 -13
- package/src/components/Login/PermissionDenied.vue +0 -109
- package/src/components/Login/RegistrationForm.vue +0 -207
- package/src/components/Login/RegistrationView.vue +0 -17
- package/src/components/Login/__snapshots__/LoginView.spec.ts.snap +0 -1051
- package/src/components/NotFound/NotFoundView.vue +0 -39
- package/src/components/PrintStatistics/PrintStatistics.vue +0 -168
- package/src/components/PrintStatistics/PrintStatisticsView.vue +0 -15
- package/src/components/PrinterGrid/HomeToolbar.vue +0 -90
- package/src/components/PrinterGrid/PrinterGrid.vue +0 -164
- package/src/components/PrinterGrid/PrinterGridTile.vue +0 -438
- package/src/components/PrinterGrid/PrinterGridView.vue +0 -210
- package/src/components/PrinterList/FileControlList.vue +0 -40
- package/src/components/PrinterList/PrinterDetails.vue +0 -91
- package/src/components/PrinterList/PrintersView.vue +0 -492
- package/src/components/Settings/AccountSettings.vue +0 -163
- package/src/components/Settings/DiagnosticsSettings.vue +0 -137
- package/src/components/Settings/EmergencyCommands.vue +0 -265
- package/src/components/Settings/FloorSettings.vue +0 -276
- package/src/components/Settings/GridSettings.vue +0 -127
- package/src/components/Settings/OctoPrintSettings.vue +0 -188
- package/src/components/Settings/ServerProtectionSettings.vue +0 -370
- package/src/components/Settings/SettingsView.vue +0 -73
- package/src/components/Settings/SoftwareUpgradeSettings.vue +0 -297
- package/src/components/Settings/UserManagementSettings.vue +0 -257
- package/src/components/TopBar.vue +0 -147
- package/src/components.d.ts +0 -70
- package/src/directives/file-upload.directive.ts +0 -117
- package/src/directives/printer-drop-position.directive.ts +0 -92
- package/src/env.d.ts +0 -6
- package/src/main.ts +0 -76
- package/src/models/batch/reprint.dto.ts +0 -79
- package/src/models/batch.model.ts +0 -11
- package/src/models/camera-streams/camera-stream.ts +0 -19
- package/src/models/floors/floor.model.ts +0 -30
- package/src/models/octoprint/connection-options.model.ts +0 -8
- package/src/models/plugins/firmware-updates/prusa-firmware-release.model.ts +0 -57
- package/src/models/print-completions/print-completions.model.ts +0 -49
- package/src/models/printers/crud/create-printer.model.ts +0 -26
- package/src/models/printers/file-upload-commands.model.ts +0 -4
- package/src/models/printers/gcode/gcode-analysis.model.ts +0 -30
- package/src/models/printers/printer-current-job.model.ts +0 -90
- package/src/models/printers/printer-file.model.ts +0 -48
- package/src/models/printers/printer.model.ts +0 -18
- package/src/models/server/client-releases.model.ts +0 -27
- package/src/models/server/export-yaml.model.ts +0 -11
- package/src/models/server/features.model.ts +0 -37
- package/src/models/server/github-rate-limit.model.ts +0 -21
- package/src/models/server/version.model.ts +0 -14
- package/src/models/settings/printer-file-clean-settings.model.ts +0 -5
- package/src/models/settings/server-settings.dto.ts +0 -19
- package/src/models/settings/settings.model.ts +0 -57
- package/src/models/socketio-messages/socketio-message.model.ts +0 -53
- package/src/models/uploads/queued-upload.model.ts +0 -12
- package/src/models/user.model.ts +0 -15
- package/src/plugins/README.md +0 -3
- package/src/plugins/index.ts +0 -17
- package/src/plugins/vuetify.ts +0 -53
- package/src/router/index.ts +0 -192
- package/src/router/route-names.ts +0 -14
- package/src/router/utils.ts +0 -23
- package/src/shared/alert.events.ts +0 -14
- package/src/shared/app.constants.ts +0 -23
- package/src/shared/auth.constants.ts +0 -34
- package/src/shared/dialog.composable.ts +0 -41
- package/src/shared/drag.constants.ts +0 -19
- package/src/shared/experimental.constants.ts +0 -1
- package/src/shared/http-client.ts +0 -162
- package/src/shared/noun-adjectives.data.ts +0 -24
- package/src/shared/printer-grid.constants.ts +0 -5
- package/src/shared/printer-state.constants.ts +0 -194
- package/src/shared/snackbar.composable.ts +0 -66
- package/src/shared/socketio.service.ts +0 -104
- package/src/store/auth.store.ts +0 -255
- package/src/store/connection.store.ts +0 -66
- package/src/store/dialog.store.ts +0 -114
- package/src/store/features.store.ts +0 -57
- package/src/store/floor.store.ts +0 -173
- package/src/store/grid.store.ts +0 -10
- package/src/store/index.ts +0 -4
- package/src/store/printer-state.store.ts +0 -246
- package/src/store/printer.store.ts +0 -236
- package/src/store/profile.store.ts +0 -25
- package/src/store/settings.store.ts +0 -64
- package/src/store/test-printer.store.ts +0 -70
- package/src/store/uploads.store.ts +0 -75
- package/src/styles/README.md +0 -3
- package/src/styles/settings.scss +0 -10
- package/src/types/global.d.ts +0 -15
- package/src/utils/array.utils.ts +0 -15
- package/src/utils/date.utils.ts +0 -5
- package/src/utils/download-file.util.ts +0 -25
- package/src/utils/error.utils.ts +0 -3
- package/src/utils/file-size.util.ts +0 -11
- package/src/utils/id.type.ts +0 -1
- package/src/utils/sentry.util.ts +0 -8
- package/src/utils/test.util.ts +0 -30
- package/src/utils/time.utils.ts +0 -2
- package/src/utils/uploads-state.utils.ts +0 -58
- package/src/utils/validation.utils.ts +0 -14
- package/src/vite-env.d.ts +0 -7
- package/test/setup-axios-mock.ts +0 -15
- /package/{src/assets/logo.png → dist/assets/logo-CJVdjy51.png} +0 -0
- /package/{src/assets → dist/img/icons}/android-chrome-192x192.png +0 -0
|
@@ -1,297 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-card>
|
|
3
|
-
<v-toolbar color="primary">
|
|
4
|
-
<v-avatar>
|
|
5
|
-
<v-icon>upgrade</v-icon>
|
|
6
|
-
</v-avatar>
|
|
7
|
-
<v-toolbar-title> Software Upgrade </v-toolbar-title>
|
|
8
|
-
</v-toolbar>
|
|
9
|
-
<v-list lines="three">
|
|
10
|
-
<v-list-item>
|
|
11
|
-
<v-list-item-title> Current versions in use: </v-list-item-title>
|
|
12
|
-
<v-list-item-subtitle>
|
|
13
|
-
Your server's version is: {{ serverVersion }}
|
|
14
|
-
</v-list-item-subtitle>
|
|
15
|
-
<v-list-item-subtitle>
|
|
16
|
-
Your client's version is: {{ version }}
|
|
17
|
-
</v-list-item-subtitle>
|
|
18
|
-
<v-list-item-subtitle>
|
|
19
|
-
<div v-if="monsterPiVersion">
|
|
20
|
-
MonsterPi:
|
|
21
|
-
<div>Your MonsterPi version is:</div>
|
|
22
|
-
{{ monsterPiVersion }}
|
|
23
|
-
</div>
|
|
24
|
-
<div v-else>
|
|
25
|
-
MonsterPi:
|
|
26
|
-
<div>No MonsterPi distro was detected.</div>
|
|
27
|
-
</div>
|
|
28
|
-
</v-list-item-subtitle>
|
|
29
|
-
</v-list-item>
|
|
30
|
-
</v-list>
|
|
31
|
-
<v-divider />
|
|
32
|
-
<v-list
|
|
33
|
-
subheader
|
|
34
|
-
lines="three"
|
|
35
|
-
>
|
|
36
|
-
<v-list-item>
|
|
37
|
-
<v-list-item-title> Server upgrade </v-list-item-title>
|
|
38
|
-
<v-list-item-subtitle>
|
|
39
|
-
Please visit
|
|
40
|
-
<a href="https://docs.fdm-monster.net/docs/installing/">
|
|
41
|
-
the installation documentation
|
|
42
|
-
</a>
|
|
43
|
-
for instructions on how to upgrade the server.
|
|
44
|
-
</v-list-item-subtitle>
|
|
45
|
-
</v-list-item>
|
|
46
|
-
</v-list>
|
|
47
|
-
<v-divider />
|
|
48
|
-
<v-list lines="three">
|
|
49
|
-
<v-list-item>
|
|
50
|
-
<v-list-item-title> Client upgrade </v-list-item-title>
|
|
51
|
-
<v-list-item-subtitle>
|
|
52
|
-
Please visit
|
|
53
|
-
<a
|
|
54
|
-
href="https://docs.fdm-monster.net/docs/configuration/updating_client_bundle"
|
|
55
|
-
>
|
|
56
|
-
the installation documentation
|
|
57
|
-
</a>
|
|
58
|
-
for instructions on how to upgrade the client bundle.
|
|
59
|
-
</v-list-item-subtitle>
|
|
60
|
-
<v-list-item-subtitle>
|
|
61
|
-
Upgrade the client webapp for quickly retrieving small fixes and
|
|
62
|
-
features
|
|
63
|
-
</v-list-item-subtitle>
|
|
64
|
-
</v-list-item>
|
|
65
|
-
<v-list-item>
|
|
66
|
-
<v-list-item-title> Select a release to upgrade to: </v-list-item-title>
|
|
67
|
-
<v-list-item-subtitle class="mt-2">
|
|
68
|
-
Minimum required version: {{ minimum?.tag_name }}
|
|
69
|
-
</v-list-item-subtitle>
|
|
70
|
-
|
|
71
|
-
<span v-if="loading">
|
|
72
|
-
<v-alert> Loading releases... </v-alert>
|
|
73
|
-
</span>
|
|
74
|
-
<v-alert v-if="!loading && !filteredReleases?.length">
|
|
75
|
-
No releases to show.
|
|
76
|
-
</v-alert>
|
|
77
|
-
<v-radio-group v-model="selectedRelease">
|
|
78
|
-
<v-radio
|
|
79
|
-
v-for="release in filteredReleases"
|
|
80
|
-
:key="release.tag_name"
|
|
81
|
-
:disabled="isDisabledRelease(release)"
|
|
82
|
-
:label="calculateLabelDisabledReason(release)"
|
|
83
|
-
:value="release.tag_name"
|
|
84
|
-
/>
|
|
85
|
-
</v-radio-group>
|
|
86
|
-
<div>
|
|
87
|
-
<v-alert
|
|
88
|
-
v-if="showPrereleases"
|
|
89
|
-
color="primary"
|
|
90
|
-
max-width="500px"
|
|
91
|
-
>
|
|
92
|
-
You are viewing prereleases, please install such versions at your
|
|
93
|
-
own risk!
|
|
94
|
-
</v-alert>
|
|
95
|
-
</div>
|
|
96
|
-
<div>
|
|
97
|
-
<v-checkbox
|
|
98
|
-
v-model="allowDowngrade"
|
|
99
|
-
label="Allow downgrade"
|
|
100
|
-
/>
|
|
101
|
-
<v-checkbox
|
|
102
|
-
v-model="showPrereleases"
|
|
103
|
-
:disabled="getIsCurrentUnstable"
|
|
104
|
-
:label="
|
|
105
|
-
getIsCurrentUnstable
|
|
106
|
-
? 'Show prerelease versions (Currently already on prerelease version)'
|
|
107
|
-
: 'Show prerelease versions'
|
|
108
|
-
"
|
|
109
|
-
/>
|
|
110
|
-
</div>
|
|
111
|
-
<v-btn
|
|
112
|
-
class="mt-2 mr-4"
|
|
113
|
-
color="secondary"
|
|
114
|
-
@click="loadReleases()"
|
|
115
|
-
>
|
|
116
|
-
Reload release version list
|
|
117
|
-
</v-btn>
|
|
118
|
-
<v-btn
|
|
119
|
-
:disabled="
|
|
120
|
-
!selectedRelease?.length || selectedRelease === current?.tag_name
|
|
121
|
-
"
|
|
122
|
-
class="mt-2"
|
|
123
|
-
color="primary"
|
|
124
|
-
variant="flat"
|
|
125
|
-
@click="clickUpdateClient(selectedRelease)"
|
|
126
|
-
>
|
|
127
|
-
<v-icon>upgrade</v-icon>
|
|
128
|
-
Upgrade/downgrade client
|
|
129
|
-
</v-btn>
|
|
130
|
-
</v-list-item>
|
|
131
|
-
</v-list>
|
|
132
|
-
</v-card>
|
|
133
|
-
</template>
|
|
134
|
-
<script lang="ts" setup>
|
|
135
|
-
import { AppService } from '@/backend/app.service'
|
|
136
|
-
import { computed, onMounted, ref } from 'vue'
|
|
137
|
-
import { version as packageJsonVersion } from '../../../package.json'
|
|
138
|
-
import { IRelease } from '@/models/server/client-releases.model'
|
|
139
|
-
import { compare, minor } from 'semver'
|
|
140
|
-
import { useFeatureStore } from '@/store/features.store'
|
|
141
|
-
|
|
142
|
-
const errorMessage = ref('')
|
|
143
|
-
const loading = ref(true)
|
|
144
|
-
const rateLimitExceeded = ref(false)
|
|
145
|
-
const allowDowngrade = ref(false)
|
|
146
|
-
const serverVersion = ref('')
|
|
147
|
-
const monsterPiVersion = ref<string>('')
|
|
148
|
-
const version = ref(packageJsonVersion)
|
|
149
|
-
const current = ref<IRelease>()
|
|
150
|
-
const minimum = ref<IRelease>()
|
|
151
|
-
const selectedRelease = ref<string>()
|
|
152
|
-
const showPrereleases = ref<boolean>(false)
|
|
153
|
-
const loadedClientReleases = ref<IRelease[]>([])
|
|
154
|
-
const featureStore = useFeatureStore()
|
|
155
|
-
|
|
156
|
-
onMounted(async () => {
|
|
157
|
-
await loadReleases()
|
|
158
|
-
|
|
159
|
-
const versionSpec = await AppService.getVersion()
|
|
160
|
-
serverVersion.value = versionSpec.version
|
|
161
|
-
monsterPiVersion.value = versionSpec.monsterPi?.trim() || ''
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
async function loadReleases() {
|
|
165
|
-
loading.value = true
|
|
166
|
-
errorMessage.value = ''
|
|
167
|
-
rateLimitExceeded.value = false
|
|
168
|
-
|
|
169
|
-
if (featureStore.hasFeature('githubRateLimitApi')) {
|
|
170
|
-
try {
|
|
171
|
-
const rateLimit = await AppService.getGithubRateLimit()
|
|
172
|
-
if (rateLimit.rate.remaining === 0) {
|
|
173
|
-
const limitResetAt = new Date(rateLimit.rate.reset)
|
|
174
|
-
const time = limitResetAt.toLocaleTimeString()
|
|
175
|
-
const diff = rateLimit.rate.reset * 1000 - Date.now()
|
|
176
|
-
const diffMinutes = Math.ceil(diff / 60000)
|
|
177
|
-
errorMessage.value = `Server has reached a rate limit of the Github API. This limit will be reset at ${time} (in ${diffMinutes} minutes)`
|
|
178
|
-
loading.value = false
|
|
179
|
-
rateLimitExceeded.value = true
|
|
180
|
-
return
|
|
181
|
-
}
|
|
182
|
-
} catch (e) {
|
|
183
|
-
loading.value = false
|
|
184
|
-
return
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
try {
|
|
189
|
-
const clientReleases = await AppService.getClientReleases()
|
|
190
|
-
current.value = clientReleases.current
|
|
191
|
-
minimum.value = clientReleases.minimum
|
|
192
|
-
loadedClientReleases.value = clientReleases.releases
|
|
193
|
-
} catch (e: any) {
|
|
194
|
-
errorMessage.value = 'An error occurred loading the releases: ' + e.message
|
|
195
|
-
} finally {
|
|
196
|
-
loading.value = false
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const filteredReleases = computed(() => {
|
|
201
|
-
return loadedClientReleases.value.filter((release) => {
|
|
202
|
-
const isMinimumVersionOrHigher =
|
|
203
|
-
minor(release.tag_name) === minor(minimum.value!.tag_name)
|
|
204
|
-
const isReleaseCandidate = isVersionUnstable(release)
|
|
205
|
-
const isDraft = release.draft
|
|
206
|
-
|
|
207
|
-
return (
|
|
208
|
-
isMinimumVersionOrHigher &&
|
|
209
|
-
(isCurrentUnstable() || showPrereleases.value || !isReleaseCandidate) &&
|
|
210
|
-
!isDraft
|
|
211
|
-
)
|
|
212
|
-
})
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
const getIsCurrentUnstable = computed(() => {
|
|
216
|
-
return isCurrentUnstable()
|
|
217
|
-
})
|
|
218
|
-
|
|
219
|
-
function isCurrentUnstable() {
|
|
220
|
-
// Determine if current is rc/unstable, meaning we should ignore prerelease filter checkbox
|
|
221
|
-
const currentRelease = current.value
|
|
222
|
-
return isVersionUnstable(currentRelease)
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function isDisabledRelease(release: IRelease) {
|
|
226
|
-
return (
|
|
227
|
-
isCurrentRelease(release) ||
|
|
228
|
-
!isUpgradeOrAllowedDowngrade(release, current.value) ||
|
|
229
|
-
isBelowMinimum(release)
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
function calculateLabelDisabledReason(release: IRelease) {
|
|
234
|
-
const prefix = isVersionUnstable(release)
|
|
235
|
-
? `${release.tag_name}, unstable`
|
|
236
|
-
: release.tag_name
|
|
237
|
-
|
|
238
|
-
if (isCurrentRelease(release)) {
|
|
239
|
-
return `${prefix}, currently installed`
|
|
240
|
-
}
|
|
241
|
-
if (isBelowMinimum(release)) {
|
|
242
|
-
return `${prefix}, below minimum`
|
|
243
|
-
}
|
|
244
|
-
if (!isUpgradeOrAllowedDowngrade(release, current.value)) {
|
|
245
|
-
return `${prefix}, downgrade not allowed`
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
return prefix
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
function isVersionUnstable(release?: IRelease) {
|
|
252
|
-
if (release?.tag_name?.length) {
|
|
253
|
-
return (
|
|
254
|
-
release.prerelease ||
|
|
255
|
-
release.tag_name.includes('rc') ||
|
|
256
|
-
release.tag_name.includes('unstable')
|
|
257
|
-
)
|
|
258
|
-
}
|
|
259
|
-
return false
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function isBelowMinimum(release: IRelease) {
|
|
263
|
-
return compare(release.tag_name, minimum.value!.tag_name) === -1
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
function isUpgradeOrAllowedDowngrade(release: IRelease, current?: IRelease) {
|
|
267
|
-
// If no current release is known, we need to throw
|
|
268
|
-
if (!current) {
|
|
269
|
-
throw new Error('No current release is known, cannot compare.')
|
|
270
|
-
}
|
|
271
|
-
if (allowDowngrade.value) {
|
|
272
|
-
return true
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return (
|
|
276
|
-
compare(release.tag_name, current.tag_name) !== -1 &&
|
|
277
|
-
compare(release.tag_name, minimum.value!.tag_name) !== -1
|
|
278
|
-
)
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
function isCurrentRelease(release: IRelease) {
|
|
282
|
-
return release.tag_name === current.value?.tag_name
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async function clickUpdateClient(version?: string) {
|
|
286
|
-
if (
|
|
287
|
-
!confirm(
|
|
288
|
-
'Are you sure? This might cause breaking changes, if the server is outdated'
|
|
289
|
-
)
|
|
290
|
-
) {
|
|
291
|
-
return
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
await AppService.updateClientDistGithub(version, allowDowngrade.value)
|
|
295
|
-
location.reload()
|
|
296
|
-
}
|
|
297
|
-
</script>
|
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-card>
|
|
3
|
-
<v-toolbar color="primary">
|
|
4
|
-
<v-avatar>
|
|
5
|
-
<v-icon>settings</v-icon>
|
|
6
|
-
</v-avatar>
|
|
7
|
-
<v-toolbar-title> Users </v-toolbar-title>
|
|
8
|
-
</v-toolbar>
|
|
9
|
-
<GridLoader
|
|
10
|
-
v-if="loading"
|
|
11
|
-
:size="20"
|
|
12
|
-
color="#a70015"
|
|
13
|
-
style="margin: 250px; position: absolute"
|
|
14
|
-
/>
|
|
15
|
-
<v-list lines="three">
|
|
16
|
-
<v-list-subheader> Showing all users </v-list-subheader>
|
|
17
|
-
|
|
18
|
-
<v-list-item
|
|
19
|
-
v-for="(user, index) in users"
|
|
20
|
-
:key="index"
|
|
21
|
-
class="pl-6"
|
|
22
|
-
style="
|
|
23
|
-
max-width: 800px;
|
|
24
|
-
border-top: 1px solid grey;
|
|
25
|
-
border-bottom: 1px solid grey;
|
|
26
|
-
"
|
|
27
|
-
>
|
|
28
|
-
<v-list-item-content
|
|
29
|
-
:class="
|
|
30
|
-
isCurrentAccount(user) ? 'pl-6 grey darken-3' : 'pl-6 grey darken-4'
|
|
31
|
-
"
|
|
32
|
-
>
|
|
33
|
-
<v-list-item-title>
|
|
34
|
-
User '{{ user.username }}'
|
|
35
|
-
<strong
|
|
36
|
-
v-if="isCurrentAccount(user)"
|
|
37
|
-
class="text--primary float-end mr-5 mt-2"
|
|
38
|
-
>
|
|
39
|
-
Your account
|
|
40
|
-
</strong>
|
|
41
|
-
</v-list-item-title>
|
|
42
|
-
<v-list-item-subtitle />
|
|
43
|
-
<span class="text-grey-darken-4">
|
|
44
|
-
<ul>
|
|
45
|
-
<li>
|
|
46
|
-
<span
|
|
47
|
-
v-if="user.isVerified"
|
|
48
|
-
class="text-success"
|
|
49
|
-
>
|
|
50
|
-
Account verified
|
|
51
|
-
</span>
|
|
52
|
-
<span
|
|
53
|
-
v-else
|
|
54
|
-
class="text-error"
|
|
55
|
-
>
|
|
56
|
-
Account not verified
|
|
57
|
-
</span>
|
|
58
|
-
</li>
|
|
59
|
-
<li>Created at {{ formatIntlDate(user.createdAt) }}</li>
|
|
60
|
-
<li v-if="user.isDemoUser">Demo user account</li>
|
|
61
|
-
|
|
62
|
-
<li>
|
|
63
|
-
Role(s)
|
|
64
|
-
<ul>
|
|
65
|
-
<li v-if="user.isRootUser">
|
|
66
|
-
<v-chip
|
|
67
|
-
class="mb-2 mt-2"
|
|
68
|
-
size="small"
|
|
69
|
-
>
|
|
70
|
-
OWNER
|
|
71
|
-
</v-chip>
|
|
72
|
-
</li>
|
|
73
|
-
<li
|
|
74
|
-
v-for="role of convertRoles(user.roles)"
|
|
75
|
-
:key="role"
|
|
76
|
-
>
|
|
77
|
-
<v-chip
|
|
78
|
-
class="mb-2 mt-2"
|
|
79
|
-
size="small"
|
|
80
|
-
>
|
|
81
|
-
{{ role }}
|
|
82
|
-
</v-chip>
|
|
83
|
-
</li>
|
|
84
|
-
</ul>
|
|
85
|
-
</li>
|
|
86
|
-
</ul>
|
|
87
|
-
</span>
|
|
88
|
-
</v-list-item-content>
|
|
89
|
-
<v-list-item-action>
|
|
90
|
-
<v-btn
|
|
91
|
-
:disabled="isCurrentAccount(user) || user.isRootUser"
|
|
92
|
-
:color="user.isVerified ? 'error darken-4' : 'success'"
|
|
93
|
-
@click="verifyUser(user, !user.isVerified)"
|
|
94
|
-
>
|
|
95
|
-
<v-icon class="mr-2">shield</v-icon>
|
|
96
|
-
<span v-if="!user.isVerified"> Verify account </span>
|
|
97
|
-
<span v-if="user.isVerified"> Unverify account </span>
|
|
98
|
-
</v-btn>
|
|
99
|
-
<v-btn
|
|
100
|
-
:color="user.isRootUser ? 'error darken-4' : 'success'"
|
|
101
|
-
:disabled="isCurrentAccount(user) || !profile?.isRootUser"
|
|
102
|
-
class="mt-2"
|
|
103
|
-
@click="setRootUser(user, !user.isRootUser)"
|
|
104
|
-
>
|
|
105
|
-
<v-icon class="mr-2">key</v-icon>
|
|
106
|
-
<span v-if="user.isRootUser"> Remove owner </span>
|
|
107
|
-
<span v-if="!user.isRootUser"> Set owner </span>
|
|
108
|
-
</v-btn>
|
|
109
|
-
<v-btn
|
|
110
|
-
:disabled="isCurrentAccount(user) || user.isRootUser"
|
|
111
|
-
class="mt-2"
|
|
112
|
-
color="error-darken-2"
|
|
113
|
-
@click="deleteUser(user)"
|
|
114
|
-
>
|
|
115
|
-
<v-icon class="mr-2">delete</v-icon>
|
|
116
|
-
Delete
|
|
117
|
-
</v-btn>
|
|
118
|
-
</v-list-item-action>
|
|
119
|
-
</v-list-item>
|
|
120
|
-
</v-list>
|
|
121
|
-
</v-card>
|
|
122
|
-
</template>
|
|
123
|
-
|
|
124
|
-
<script lang="ts" setup>
|
|
125
|
-
import { ref } from 'vue'
|
|
126
|
-
import { UserService } from '@/backend/user.service'
|
|
127
|
-
import { Role, User } from '@/models/user.model'
|
|
128
|
-
import { formatIntlDate } from '@/utils/date.utils'
|
|
129
|
-
import GridLoader from '@/components/Generic/Loaders/GridLoader.vue'
|
|
130
|
-
import { useQuery } from '@tanstack/vue-query'
|
|
131
|
-
import { useSnackbar } from '@/shared/snackbar.composable'
|
|
132
|
-
|
|
133
|
-
const snackbar = useSnackbar()
|
|
134
|
-
const loading = ref<boolean>(false)
|
|
135
|
-
const profile = ref<User>()
|
|
136
|
-
const users = ref<User[]>([])
|
|
137
|
-
const roles = ref<Role[]>([])
|
|
138
|
-
|
|
139
|
-
async function loadData() {
|
|
140
|
-
loading.value = true
|
|
141
|
-
try {
|
|
142
|
-
profile.value = await UserService.getProfile()
|
|
143
|
-
roles.value = await UserService.listRoles()
|
|
144
|
-
users.value = await UserService.listUsers()
|
|
145
|
-
} catch (e) {
|
|
146
|
-
loading.value = false
|
|
147
|
-
console.error(e)
|
|
148
|
-
throw e
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
loading.value = false
|
|
152
|
-
|
|
153
|
-
return {
|
|
154
|
-
users,
|
|
155
|
-
roles,
|
|
156
|
-
profile
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
const userQuery = useQuery({
|
|
161
|
-
queryKey: ['userRolesProfile'],
|
|
162
|
-
queryFn: loadData
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
function convertRoles(roleIds: (string | number)[]): (string | undefined)[] {
|
|
166
|
-
return roleIds.map((roleId) => roles.value.find((r) => r.id == roleId)?.name)
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function isCurrentAccount(user: User): boolean {
|
|
170
|
-
return user.id == profile.value?.id
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async function deleteUser(user: User) {
|
|
174
|
-
if (!confirm(`Are you sure you want to delete ${user.username}?`)) {
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
loading.value = true
|
|
180
|
-
await UserService.deleteUser(user.id)
|
|
181
|
-
await userQuery.refetch()
|
|
182
|
-
} catch (e) {
|
|
183
|
-
loading.value = false
|
|
184
|
-
console.error(e)
|
|
185
|
-
throw e
|
|
186
|
-
}
|
|
187
|
-
loading.value = false
|
|
188
|
-
|
|
189
|
-
snackbar.info(`User ${user.username} deleted`)
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
async function verifyUser(user: User, isVerified: boolean = true) {
|
|
193
|
-
if (user.isRootUser) {
|
|
194
|
-
snackbar.error('You are not allowed to do perform this action on an owner')
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
if (
|
|
198
|
-
!confirm(
|
|
199
|
-
`Are you sure you want to ${isVerified ? 'verify' : 'unverify'} ${user.username}?`
|
|
200
|
-
)
|
|
201
|
-
) {
|
|
202
|
-
return
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
loading.value = true
|
|
207
|
-
await UserService.setUserVerified(user.id, isVerified)
|
|
208
|
-
await userQuery.refetch()
|
|
209
|
-
} catch (e) {
|
|
210
|
-
loading.value = false
|
|
211
|
-
console.error(e)
|
|
212
|
-
throw e
|
|
213
|
-
}
|
|
214
|
-
loading.value = false
|
|
215
|
-
|
|
216
|
-
snackbar.info(
|
|
217
|
-
isVerified
|
|
218
|
-
? `User ${user.username} verified`
|
|
219
|
-
: `User ${user.username} unverified`
|
|
220
|
-
)
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
async function setRootUser(user: User, isRootUser: boolean = true) {
|
|
224
|
-
if (!profile.value?.isRootUser) {
|
|
225
|
-
snackbar.error(
|
|
226
|
-
"You are not allowed to do perform this action as you're not an owner"
|
|
227
|
-
)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
if (
|
|
231
|
-
!confirm(
|
|
232
|
-
`You are about to ${isRootUser ? 'set' : 'remove'} owner rights on ${
|
|
233
|
-
user.username
|
|
234
|
-
}. Are you sure?`
|
|
235
|
-
)
|
|
236
|
-
) {
|
|
237
|
-
return
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
try {
|
|
241
|
-
loading.value = true
|
|
242
|
-
await UserService.setRootUser(user.id, isRootUser)
|
|
243
|
-
await userQuery.refetch()
|
|
244
|
-
} catch (e) {
|
|
245
|
-
loading.value = false
|
|
246
|
-
console.error(e)
|
|
247
|
-
throw e
|
|
248
|
-
}
|
|
249
|
-
loading.value = false
|
|
250
|
-
|
|
251
|
-
snackbar.info(
|
|
252
|
-
isRootUser
|
|
253
|
-
? `User ${user.username} set to owner`
|
|
254
|
-
: `User ${user.username} is no longer owner`
|
|
255
|
-
)
|
|
256
|
-
}
|
|
257
|
-
</script>
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<v-app-bar color="primary">
|
|
3
|
-
<v-toolbar-title class="text-uppercase text-white">
|
|
4
|
-
<span class="font-weight-light"> FDM </span>
|
|
5
|
-
<strong> Monster </strong>
|
|
6
|
-
</v-toolbar-title>
|
|
7
|
-
|
|
8
|
-
<v-spacer v-if="isDemoMode" />
|
|
9
|
-
<h2
|
|
10
|
-
v-if="isDemoMode"
|
|
11
|
-
class="text-uppercase text--white"
|
|
12
|
-
>
|
|
13
|
-
DEMO MODE
|
|
14
|
-
</h2>
|
|
15
|
-
<v-spacer />
|
|
16
|
-
|
|
17
|
-
<PrintJobsMenu />
|
|
18
|
-
|
|
19
|
-
<v-menu
|
|
20
|
-
v-if="authStore.hasAuthToken && !authStore.isLoginExpired"
|
|
21
|
-
:close-on-content-click="false"
|
|
22
|
-
location="bottom right"
|
|
23
|
-
open-on-hover
|
|
24
|
-
transition="slide-y-transition"
|
|
25
|
-
>
|
|
26
|
-
<template #activator="{ props }">
|
|
27
|
-
<!--Theme?-->
|
|
28
|
-
<v-btn
|
|
29
|
-
class="ml-2"
|
|
30
|
-
color="secondary"
|
|
31
|
-
theme="dark"
|
|
32
|
-
v-bind="props"
|
|
33
|
-
>
|
|
34
|
-
<v-icon class="mr-2">person</v-icon>
|
|
35
|
-
{{ username }}
|
|
36
|
-
</v-btn>
|
|
37
|
-
</template>
|
|
38
|
-
|
|
39
|
-
<v-list>
|
|
40
|
-
<v-list-item
|
|
41
|
-
v-for="(item, index) in items"
|
|
42
|
-
:key="index"
|
|
43
|
-
:to="item.path"
|
|
44
|
-
:title="item.title"
|
|
45
|
-
:prepend-avatar="item.icon"
|
|
46
|
-
link
|
|
47
|
-
/>
|
|
48
|
-
</v-list>
|
|
49
|
-
</v-menu>
|
|
50
|
-
|
|
51
|
-
<span
|
|
52
|
-
v-if="isDevEnv && expiry"
|
|
53
|
-
class="ml-2"
|
|
54
|
-
>
|
|
55
|
-
AuthExp {{ expiry }}
|
|
56
|
-
</span>
|
|
57
|
-
|
|
58
|
-
<span
|
|
59
|
-
v-if="isDevEnv"
|
|
60
|
-
class="ml-2"
|
|
61
|
-
>
|
|
62
|
-
<small>
|
|
63
|
-
S{{ socketState.setup ? 1 : 0 }} C{{ socketState.connected ? 1 : 0 }}
|
|
64
|
-
{{ socketState.id }}
|
|
65
|
-
</small>
|
|
66
|
-
</span>
|
|
67
|
-
|
|
68
|
-
<TooltipButton
|
|
69
|
-
v-if="authStore.loginRequired === true"
|
|
70
|
-
tooltip="Go back to login"
|
|
71
|
-
text="Logout"
|
|
72
|
-
color="secondary"
|
|
73
|
-
icon="logout"
|
|
74
|
-
@click="logout()"
|
|
75
|
-
/>
|
|
76
|
-
|
|
77
|
-
<v-btn
|
|
78
|
-
v-if="authStore.loginRequired === true"
|
|
79
|
-
class="ml-2"
|
|
80
|
-
>
|
|
81
|
-
<v-icon class="mr-2">logout</v-icon>
|
|
82
|
-
Logout
|
|
83
|
-
</v-btn>
|
|
84
|
-
|
|
85
|
-
<HelpOverlay />
|
|
86
|
-
</v-app-bar>
|
|
87
|
-
</template>
|
|
88
|
-
|
|
89
|
-
<script lang="ts" setup>
|
|
90
|
-
import { computed, ref } from 'vue'
|
|
91
|
-
import { useRouter } from 'vue-router'
|
|
92
|
-
import { useIntervalFn } from '@vueuse/core'
|
|
93
|
-
import PrintJobsMenu from '@/components/Generic/PrintJobsMenu.vue'
|
|
94
|
-
import { useAuthStore } from '@/store/auth.store'
|
|
95
|
-
import { useProfileStore } from '@/store/profile.store'
|
|
96
|
-
import { routeToLogin } from '@/router/utils'
|
|
97
|
-
import { isDevEnv, isProdEnv } from '@/shared/app.constants'
|
|
98
|
-
import { socketState } from '@/store/connection.store'
|
|
99
|
-
|
|
100
|
-
const profileStore = useProfileStore()
|
|
101
|
-
const authStore = useAuthStore()
|
|
102
|
-
const router = useRouter()
|
|
103
|
-
const items = [
|
|
104
|
-
{ title: 'Open Profile', icon: 'person', path: '/settings/account' }
|
|
105
|
-
]
|
|
106
|
-
|
|
107
|
-
const now = ref(Date.now())
|
|
108
|
-
if (isDevEnv) {
|
|
109
|
-
useIntervalFn(() => {
|
|
110
|
-
now.value = Date.now()
|
|
111
|
-
}, 1000)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const expiry = computed(() => {
|
|
115
|
-
if (isProdEnv) {
|
|
116
|
-
return ''
|
|
117
|
-
}
|
|
118
|
-
if (!authStore.tokenClaims?.exp) {
|
|
119
|
-
return ''
|
|
120
|
-
}
|
|
121
|
-
const diffValue = authStore.tokenClaims.exp - now.value / 1000
|
|
122
|
-
return `${Math.round(diffValue)}s`
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
const username = computed(() => {
|
|
126
|
-
return profileStore.username
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
const isDemoMode = computed(() => {
|
|
130
|
-
return authStore.isDemoMode
|
|
131
|
-
})
|
|
132
|
-
|
|
133
|
-
async function logout() {
|
|
134
|
-
await authStore.logout(true)
|
|
135
|
-
await routeToLogin(router)
|
|
136
|
-
}
|
|
137
|
-
</script>
|
|
138
|
-
|
|
139
|
-
<style lang="scss">
|
|
140
|
-
.border-time {
|
|
141
|
-
border: 1px solid white;
|
|
142
|
-
|
|
143
|
-
* {
|
|
144
|
-
border: none;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
</style>
|