Skip to content

Commit bf30b20

Browse files
authored
Merge pull request #3275 from Annoraaq/v3-sketch-page-settings
V3 sketch page top bar
2 parents 0135c64 + e04c629 commit bf30b20

File tree

6 files changed

+420
-15
lines changed

6 files changed

+420
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<!--
2+
Copyright 2025 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<template>
17+
<div>
18+
<h3>Rename sketch</h3>
19+
<br />
20+
<v-form @submit.prevent="renameSketch()">
21+
<v-text-field
22+
variant="outlined"
23+
density="compact"
24+
autofocus
25+
v-model="newSketchName"
26+
@focus="$event.target.select()"
27+
clearable
28+
:rules="sketchNameRules"
29+
>
30+
</v-text-field>
31+
<v-card-actions>
32+
<v-spacer></v-spacer>
33+
<v-btn text @click="closeDialog()"> Cancel </v-btn>
34+
<v-btn :disabled="!newSketchName || newSketchName.length > 255" text color="primary" @click="renameSketch()">
35+
Save
36+
</v-btn>
37+
</v-card-actions>
38+
</v-form>
39+
</div>
40+
</template>
41+
42+
<script>
43+
import ApiClient from '../utils/RestApiClient'
44+
import { useAppStore } from "@/stores/app";
45+
46+
export default {
47+
data() {
48+
return {
49+
appStore: useAppStore(),
50+
newSketchName: '',
51+
sketchNameRules: [
52+
(v) => !!v || 'Sketch name is required.',
53+
(v) => (v && v.length <= 255) || 'Sketch name is too long.',
54+
],
55+
}
56+
},
57+
computed: {
58+
sketch() {
59+
return this.appStore.sketch
60+
},
61+
},
62+
methods: {
63+
renameSketch() {
64+
ApiClient.saveSketchSummary(this.sketch.id, this.newSketchName, '')
65+
.then((response) => {
66+
this.appStore.updateSketch(this.sketch.id);
67+
})
68+
.catch((e) => {
69+
console.error(e)
70+
})
71+
this.$emit('close')
72+
},
73+
closeDialog: function () {
74+
this.newSketchName = this.sketch.name
75+
this.$emit('close')
76+
},
77+
},
78+
created() {
79+
this.newSketchName = this.sketch.name
80+
},
81+
}
82+
</script>
83+
84+
<!-- CSS scoped to this component only -->
85+
<style scoped lang="scss"></style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<!--
2+
Copyright 2025 Google Inc. All rights reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<template>
17+
<v-card class="pa-4 pt-5" min-height="800px">
18+
<v-card-title class="pl-6">Settings</v-card-title>
19+
<v-list class="pr-3" v-if="settings" two-line subheader flat>
20+
<v-list-subheader class="ml-3">Layout</v-list-subheader>
21+
<v-list-item>
22+
<div class="d-flex align-center pl-3">
23+
<v-switch v-model="settings.showLeftPanel" color="primary" @change="saveSettings()" hide-details></v-switch>
24+
<div class="pl-5">
25+
<v-list-item-title>Show side panel</v-list-item-title>
26+
<v-list-item-subtitle
27+
>Select if the side panel should be expanded or collapsed by default</v-list-item-subtitle
28+
>
29+
</div>
30+
</div>
31+
</v-list-item>
32+
<v-list-item v-if="systemSettings.LLM_PROVIDER">
33+
<div class="d-flex align-center pl-3">
34+
<v-switch v-model="settings.generateQuery" color="primary" @change="saveSettings()"></v-switch>
35+
<div class="pl-5">
36+
<v-list-item-title>AI generated queries</v-list-item-title>
37+
<v-list-item-subtitle
38+
>Select to enable experimental AI query suggestions for DFIQ questions</v-list-item-subtitle
39+
>
40+
</div>
41+
</div>
42+
</v-list-item>
43+
</v-list>
44+
</v-card>
45+
</template>
46+
47+
<script>
48+
import ApiClient from '../utils/RestApiClient'
49+
import { useAppStore } from "@/stores/app";
50+
51+
const DEFAULT_SETTINGS = {
52+
showLeftPanel: true,
53+
}
54+
55+
export default {
56+
data() {
57+
return {
58+
appStore: useAppStore(),
59+
settings: {
60+
showLeftPanel: true,
61+
generateQuery: true,
62+
},
63+
}
64+
},
65+
computed: {
66+
sketch() {
67+
return this.appStore.sketch
68+
},
69+
systemSettings() {
70+
return this.appStore.systemSettings
71+
},
72+
userSettings() {
73+
return this.appStore.settings
74+
},
75+
},
76+
methods: {
77+
saveSettings() {
78+
ApiClient.saveUserSettings(this.settings)
79+
.then(() => this.appStore.updateUserSettings())
80+
.catch((error) => {
81+
console.log(error)
82+
})
83+
},
84+
},
85+
mounted() {
86+
this.settings = { ...this.userSettings }
87+
// Set default values when the users don't have any settings saved.
88+
if (this.settings && !Object.keys(this.settings).length) {
89+
this.settings = { ...DEFAULT_SETTINGS }
90+
this.saveSettings()
91+
}
92+
},
93+
}
94+
</script>
95+
96+
<style scoped>
97+
.example {
98+
color: red;
99+
}
100+
</style>

timesketch/frontend-v3/src/layouts/AppBar.vue

+8-6
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ limitations under the License.
6868
<script>
6969
import ApiClient from '../utils/RestApiClient.js'
7070
import { useTheme } from 'vuetify'
71+
import { useAppStore } from "@/stores/app";
7172

7273
export default {
7374
setup() {
@@ -76,20 +77,21 @@ export default {
7677
},
7778
data() {
7879
return {
79-
currentUser: '',
80+
appStore: useAppStore(),
8081
};
8182
},
82-
computed: {},
83+
computed: {
84+
currentUser() {
85+
return this.appStore.currentUser;
86+
}
87+
},
8388
methods: {
8489
toggleTheme: function () {
8590
this.theme.global.name.value = this.theme.global.current.value.dark ? 'light' : 'dark';
8691
},
8792
},
8893
created: function () {
89-
ApiClient.getLoggedInUser().then((response) => {
90-
let currentUser = response.data.objects[0].username;
91-
this.currentUser = currentUser;
92-
});
94+
this.appStore.resetState();
9395
},
9496
};
9597
</script>

timesketch/frontend-v3/src/router/index.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ const routes = [
2626
component: Home,
2727
props: true,
2828
},
29-
{
30-
path: 'sketch/:sketchId',
31-
component: Sketch,
32-
props: true,
33-
},
3429
]
3530
},
31+
{
32+
path: '/sketch/:sketchId',
33+
component: Sketch,
34+
props: true,
35+
},
3636
];
3737

3838
const router = createRouter({

timesketch/frontend-v3/src/stores/app.js

+11
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,22 @@ export const useAppStore = defineStore("app", {
5757
this.testAppStore = "🚀 Pinia state storage is operational!";
5858
},
5959

60+
resetState() {
61+
ApiClient.getLoggedInUser().then((response) => {
62+
let currentUser = response.data.objects[0].username;
63+
this.$reset();
64+
this.currentUser = currentUser;
65+
})
66+
},
67+
6068
async updateSketch(sketchId) {
6169
try {
6270
const response = await ApiClient.getSketch(sketchId);
6371
this.sketch = response.data.objects[0];
6472
this.meta = response.data.meta;
73+
const userResp = await ApiClient.getLoggedInUser();
74+
let currentUser = userResp.data.objects[0].username;
75+
this.currentUser = currentUser;
6576
await this.updateTimelineTags(sketchId);
6677
await this.updateDataTypes(sketchId);
6778
} catch (e) {

0 commit comments

Comments
 (0)