5
5
<sidebar class =" app-sidebar"
6
6
@show =" show"
7
7
:config =" config"
8
+ :bookmarks =" bookmarks"
9
+ ref =" sidebar"
8
10
></sidebar >
9
11
</pane >
10
12
<pane key =" 2" :size =" 100 - sidebarSize" class =" app-main" >
19
21
</ul >
20
22
<vue-simple-context-menu
21
23
element-id =" app-main-nav-menu"
22
- :options =" options "
24
+ :options =" menuOptions "
23
25
ref =" appMainNavMenu"
24
26
@option-clicked =" menuOptionClicked"
25
27
/>
@@ -134,7 +136,9 @@ import axios from 'axios';
134
136
import { v4 as uuidv4 } from ' uuid' ;
135
137
import { defineComponent , ref } from ' vue' ;
136
138
import { Splitpanes , Pane } from ' splitpanes' ;
137
- import { setColor , prepareHref , splitPath } from " ../commons" ;
139
+ import { setColor , prepareHref , splitPath , EDITOR_THEME_KEY , EDITOR_MODE_KEY , EDITOR_COLOR_KEY , SHOW_HIDDEN_FILES_KEY , BOOKMARKS_KEY , WORKSPACE_UUID } from " ../commons" ;
140
+ import { TabState } from ' ../tabs.js' ;
141
+
138
142
import VueSimpleContextMenu from ' vue-simple-context-menu' ;
139
143
import Sidebar from ' ./Sidebar.vue' ;
140
144
import FilesEditorContainer from ' ./FilesEditorContainer.vue' ;
@@ -144,22 +148,6 @@ import Workspace from './Workspace.vue';
144
148
import ErrorDialog from ' ./dialogs/ErrorDialog.vue' ;
145
149
import CloseTabDialog from ' ./dialogs/CloseTabDialog.vue' ;
146
150
147
- const WORKSPACE_UUID = ' d15216ca-854d-4705-bff5-1887e8bf1180' ;
148
-
149
- class TabState {
150
- constructor (name , component , target ) {
151
- if (component == Workspace) {
152
- this .uuid = WORKSPACE_UUID ;
153
- } else {
154
- this .uuid = uuidv4 ();
155
- }
156
- this .name = name;
157
- this .component = component;
158
- this .target = target;
159
- this .closed = false ;
160
- }
161
- }
162
-
163
151
export default defineComponent ({
164
152
components: {
165
153
' splitpanes' : Splitpanes,
@@ -178,23 +166,14 @@ export default defineComponent({
178
166
tabs: [],
179
167
selectedTab: null , // selected tab
180
168
config: {
181
- theme: localStorage .getItem (' airflow_code_editor_theme ' ) || ' default' , // editor theme
182
- mode: localStorage .getItem (' airflow_code_editor_mode ' ) || ' default' , // edit mode (default, vim, etc...)
183
- color: localStorage .getItem (' airflow_code_editor_color ' ) || ' Light' , // light/dark mode
184
- showHiddenFiles: localStorage .getItem (' airflow_code_editor_show_hidden_files ' ) == ' true' ,
169
+ theme: localStorage .getItem (EDITOR_THEME_KEY ) || ' default' , // editor theme
170
+ mode: localStorage .getItem (EDITOR_MODE_KEY ) || ' default' , // edit mode (default, vim, etc...)
171
+ color: localStorage .getItem (EDITOR_COLOR_KEY ) || ' Light' , // light/dark mode
172
+ showHiddenFiles: localStorage .getItem (SHOW_HIDDEN_FILES_KEY ) == ' true' ,
185
173
singleTab: false ,
186
174
},
187
175
sidebarSize: 190 * 100 / document .documentElement .clientWidth , // sidebar size (percentage)
188
- options: [
189
- {
190
- name: ' <span class="material-icons">close</span> Close' ,
191
- slug: ' close' ,
192
- },
193
- {
194
- name: ' <span class="material-icons">cancel</span> Close other tabs' ,
195
- slug: ' close_others' ,
196
- },
197
- ],
176
+ menuOptions: [],
198
177
};
199
178
},
200
179
methods: {
@@ -227,7 +206,7 @@ export default defineComponent({
227
206
this .$refs [tab .uuid ][0 ].refresh ();
228
207
}
229
208
} else {
230
- tab = new TabState (target .path , FilesEditorContainer, target);
209
+ tab = new TabState (target .path , FilesEditorContainer, target, uuidv4 () );
231
210
this .tabs .push (tab);
232
211
}
233
212
this .selectedTab = tab .uuid ;
@@ -236,7 +215,7 @@ export default defineComponent({
236
215
if (tab) {
237
216
this .$refs [tab .uuid ][0 ].refresh ();
238
217
} else {
239
- tab = new TabState (' Workspace' , Workspace);
218
+ tab = new TabState (' Workspace' , Workspace, target, WORKSPACE_UUID );
240
219
this .tabs .push (tab);
241
220
}
242
221
this .selectedTab = tab .uuid ;
@@ -245,7 +224,7 @@ export default defineComponent({
245
224
if (tab) {
246
225
this .$refs [tab .uuid ][0 ].refresh ();
247
226
} else {
248
- tab = new TabState (target .path , Search, target);
227
+ tab = new TabState (target .path , Search, target, uuidv4 () );
249
228
this .tabs .push (tab);
250
229
}
251
230
this .selectedTab = tab .uuid ;
@@ -254,7 +233,7 @@ export default defineComponent({
254
233
if (tab) {
255
234
this .$refs [tab .uuid ][0 ].refresh ();
256
235
} else {
257
- tab = new TabState (target .name , HistoryView, target);
236
+ tab = new TabState (target .name , HistoryView, target, uuidv4 () );
258
237
this .tabs .push (tab);
259
238
}
260
239
this .selectedTab = tab .uuid ;
@@ -271,17 +250,51 @@ export default defineComponent({
271
250
showMenu (event , tab ) {
272
251
// Show tab menu
273
252
if (tab) {
253
+ this .menuOptions = this .prepareMenuOptions (tab);
274
254
this .$refs .appMainNavMenu .showMenu (event , tab);
275
255
}
276
256
},
257
+ prepareMenuOptions (tab ) {
258
+ // Prepare tab menu options
259
+ const label = tab .isBookmarked () ? ' Remove bookmark' : ' Bookmark tab' ;
260
+ return [
261
+ {
262
+ name: ' <span class="material-icons">bookmark</span> ' + label,
263
+ slug: ' bookmark' ,
264
+ },
265
+ {
266
+ type: ' divider'
267
+ },
268
+ {
269
+ name: ' <span class="material-icons">close</span> Close' ,
270
+ slug: ' close' ,
271
+ },
272
+ {
273
+ name: ' <span class="material-icons">cancel</span> Close other tabs' ,
274
+ slug: ' close_others' ,
275
+ },
276
+ ];
277
+ },
277
278
async menuOptionClicked (event ) {
278
279
// Menu click
279
- if (event .option .slug == ' close_others' ) {
280
- for (const tab of this .tabs .filter (x => x != event .item && ! x .closed )) {
281
- await this .closeTab (tab);
282
- }
283
- } else if (event .option .slug == ' close' ) {
284
- await this .closeTab (event .item );
280
+ switch (event .option .slug ) {
281
+ case ' bookmark' :
282
+ if (event .item .isBookmarked ()) {
283
+ event .item .removeBookmark ();
284
+ } else {
285
+ event .item .addBookmark ();
286
+ }
287
+ // Refresh bookmarks in the sidebar
288
+ this .$refs .sidebar .refreshBookmarks ();
289
+ break ;
290
+ case ' close_others' :
291
+ for (const tab of this .tabs .filter (x => x != event .item && ! x .closed )) {
292
+ await this .closeTab (tab);
293
+ }
294
+ break ;
295
+ case ' close' :
296
+ await this .closeTab (event .item );
297
+ break
285
298
}
286
299
},
287
300
selectTab (tab ) {
0 commit comments