diff --git a/extensions/background-script.js b/extensions/background-script.js index 27e0187..a224abf 100644 --- a/extensions/background-script.js +++ b/extensions/background-script.js @@ -3,81 +3,115 @@ });*/ browser.runtime.onMessage.addListener(async (message, sender, sendResponse) => { - if (message.type === "REGISTER_INTEREST") { - let interestList = - (await browser.storage.local.get("interesetWindows")) - .interesetWindows ?? []; - // Already has interest! - if (interestList.includes(sender.tab.id)) { - return; - } - interestList.push(sender.tab.id); + if (message.type === "REGISTER_INTEREST") { + let interestList = + (await browser.storage.local.get("interesetWindows")) + .interesetWindows ?? []; + // Already has interest! + if (interestList.includes(sender.tab.id)) { + return; + } + interestList.push(sender.tab.id); - await browser.storage.local.set({ - interesetWindows: interestList, - }); + await browser.storage.local.set({ + interesetWindows: interestList, + }); - return; - } - if (message.type === "GOT_INFO_R") { - // TODO then send this information back to that page - let interestList = - (await browser.storage.local.get("interesetWindows")) - .interesetWindows ?? []; + let windowList = (await browser.storage.local.get("windows")).windows; + if (windowList) { + console.log("here sending got interest"); + browser.tabs.sendMessage(sender.tab.id, { + type: "GOT_INTEREST", + }); + } + return; + } + if (message.type === "AUTOLOAD_NOTIFY_URL") { + // TODO then send this information back to that page + let interestList = + (await browser.storage.local.get("interesetWindows")) + .interesetWindows ?? []; - interestList.forEach((a) => { - browser.tabs.sendMessage(a, message); - }); - return; - } - if (message.type === "R_GET_DATA_FROM_PAGE") { - let windowList = (await browser.storage.local.get("windows")).windows; + interestList.forEach((a) => { + browser.tabs.sendMessage(a, { + type: "MY_GET_URL_R", + url: message.url, + }); + }); + return; + } + if ( + message.type === "GOT_INFO_R" || + message.type === "AUTOLOAD_FOUND_GLASSDOOR_SEARCH" + ) { + // TODO then send this information back to that page + let interestList = + (await browser.storage.local.get("interesetWindows")) + .interesetWindows ?? []; + + interestList.forEach((a) => { + browser.tabs.sendMessage(a, message); + }); + return; + } + if (message.type === "R_GET_DATA_FROM_PAGE") { + let windowList = (await browser.storage.local.get("windows")).windows; if (!windowList) return; - const tab = await browser.tabs.get(windowList); + const tab = await browser.tabs.get(windowList); browser.tabs.sendMessage(tab.id, { type: "GET_DATA_FROM_PAGE", }); return; } - if (message.type !== "MY_GET_URL") return; + if (message.type === "CHANGE_PAGE") { + let windowList = (await browser.storage.local.get("windows")).windows; + if (!windowList) return; + const tab = await browser.tabs.get(windowList); + browser.tabs.sendMessage(tab.id, { + type: "CHANGE_PAGE", + new_url: message.new_url, + }); + return; + } + if (message.type !== "MY_GET_URL") return; - let windowList = (await browser.storage.local.get("windows")).windows; - if (!windowList) { - browser.tabs.sendMessage(sender.tab.id, { - type: "MY_GET_URL_R", - error: "Invalid number of pages marked as target", - data: windowList, - }); - return; - } + let windowList = (await browser.storage.local.get("windows")).windows; + if (!windowList) { + browser.tabs.sendMessage(sender.tab.id, { + type: "MY_GET_URL_R", + error: "Invalid number of pages marked as target", + data: windowList, + }); + return; + } - const tab = await browser.tabs.get(windowList); + const tab = await browser.tabs.get(windowList); - browser.tabs.sendMessage(tab.id, { - type: "GET_DATA_FROM_PAGE", - }); + browser.tabs.sendMessage(tab.id, { + type: "GET_DATA_FROM_PAGE", + }); - browser.tabs.sendMessage(sender.tab.id, { - type: "MY_GET_URL_R", - url: tab.url, - all_data: tab, - }); + browser.tabs.sendMessage(sender.tab.id, { + type: "MY_GET_URL_R", + url: tab.url, + all_data: tab, + }); }); async function startup() { - console.log("Exp startup application") - await browser.storage.local.set({ - windows: null, - interesetWindows: [], - }); + console.log("Exp startup application"); + await browser.storage.local.set({ + windows: null, + interesetWindows: [], + }); - // Clear the menus from the prev install / startup - browser.menus.removeAll(); - browser.menus.create({ - id: "mark-page", - title: "Mark Page As the Url target", - contexts: ["all"], - }); + // Clear the menus from the prev install / startup + browser.menus.removeAll(); + browser.menus.create({ + id: "mark-page", + title: "Mark Page As the Url target", + contexts: ["all"], + }); } browser.runtime.onInstalled.addListener(startup); @@ -85,9 +119,35 @@ browser.runtime.onStartup.addListener(startup); browser.runtime.onConnect.addListener(startup); browser.menus.onClicked.addListener(async function (e, tab) { if (e.menuItemId === "mark-page") { - console.log("set mark-page", tab.id) + console.log("set mark-page", tab.id); await browser.storage.local.set({ windows: tab.id, }); } }); + +var timeout; +var lastOrigin; + +async function detectRequest(requestDetails) { + let windowList = (await browser.storage.local.get("windows")).windows; + if (!windowList || requestDetails.tabId !== windowList) return; + if ( + requestDetails.originUrl === lastOrigin || + (!requestDetails.url.includes("glassdoor") && + !requestDetails.url.includes("linkedin")) + ) { + return; + } + console.log(`Mon: ${requestDetails.url}`); + if (timeout) clearTimeout(timeout); + timeout = setTimeout(() => { + console.log("autoload detected"); + lastOrigin = requestDetails.originUrl; + browser.tabs.sendMessage(windowList, { type: "AUTOLOAD_FINISHED" }); + }, 3000); +} + +browser.webRequest.onBeforeRequest.addListener(detectRequest, { + urls: [""], +}); diff --git a/extensions/definitions.js b/extensions/definitions.js index 1bea184..3ad8d8c 100644 --- a/extensions/definitions.js +++ b/extensions/definitions.js @@ -1,62 +1,169 @@ -browser.runtime.onMessage.addListener((message) => { - if (message.type === "MY_GET_URL_R") { - window.postMessage(message); - } else if (message.type === "GET_DATA_FROM_PAGE") { - // Parse things for linkedin - if (window.location.host.includes("linkedin")) { - if (window.location.host.includes("merchantpool1")) { - return; - } - const jobTitle = document.querySelector('h1').textContent; - const company = document.querySelector('.relative a[target="_self"]').textContent; - - const money = - document.querySelector('ul li div div div li-icon[type="job"]')?.parentNode?.parentNode?.parentNode?.parentNode?.children[1]?.children[0]?.textContent?.replaceAll(/\s{2,}/g, '') ?? - Object.values(document.querySelector('button[class="job-details-preferences-and-skills"]')?.children ?? []).find(a => a.innerText.match(/\d/) && !a.innerText.match('skill'))?.innerText ?? - ''; - - const inperson_type = (Object.values(document.querySelector('button[class="job-details-preferences-and-skills"]')?.children).find(a => a.innerText.match(/hybrid|remote|on-site/i))?.innerText?.split('\n') ?? [])[0]?.trim() ?? '' - - const location = document.querySelector('div[class^="job-details-jobs-unified-top-card__primary-description-container"]')?.children[0]?.children[0]?.innerText ?? '' - - const description = document.querySelector('article').textContent; - - browser.runtime.sendMessage({ type: "GOT_INFO_R", company, jobTitle, money, description, location, inperson_type }); +function getPageData() { + // Parse things for linkedin + if (window.location.host.includes("linkedin")) { + if (window.location.host.includes("merchantpool1")) { return; } - // Ignore everything that is no glassdoor - if (!window.location.host.includes("glassdoor")) return; - const company = document.querySelector('header[data-test="job-details-header"]') - .children[0].children[0].querySelector("h4").innerHTML; - const jobTitle = document - .querySelector('header[data-test="job-details-header"]') - .querySelector("h1").innerHTML; + const jobTitle = document.querySelector("h1").textContent; + const company = document.querySelector( + '.relative a[target="_self"]', + ).textContent; - const description = [...document.querySelector('header[data-test="job-details-header"]').parentNode.querySelectorAll('button')].filter(a => a.textContent == "Show more")[0]?.parentNode?.parentNode?.textContent; + const money = + document + .querySelector('ul li div div div li-icon[type="job"]') + ?.parentNode?.parentNode?.parentNode?.parentNode?.children[1]?.children[0]?.textContent?.replaceAll( + /\s{2,}/g, + "", + ) ?? + Object.values( + document.querySelector( + 'button[class="job-details-preferences-and-skills"]', + )?.children ?? [], + ).find( + (a) => a.innerText.match(/\d/) && !a.innerText.match("skill"), + )?.innerText ?? + ""; - let money = document.querySelectorAll('div[class^="SalaryEstimate_salaryRange"]')?.[0]?.innerText ?? ''; + const inperson_type = + (Object.values( + document.querySelector( + 'button[class="job-details-preferences-and-skills"]', + )?.children, + ) + .find((a) => a.innerText.match(/hybrid|remote|on-site/i)) + ?.innerText?.split("\n") ?? [])[0]?.trim() ?? ""; - const location = document.querySelector('div[data-test="location"]')?.innerText ?? ''; + const location = + document.querySelector( + 'div[class^="job-details-jobs-unified-top-card__primary-description-container"]', + )?.children[0]?.children[0]?.innerText ?? ""; - const moneySectionNode = document.querySelector('section>section'); - if (moneySectionNode && ["Base pay range", "Base pay"].includes(moneySectionNode.querySelector('h2')?.textContent)) { - money = moneySectionNode.querySelector("div>div>div").children[1]?.textContent ?? '' + const description = document.querySelector("article").textContent; + + let status = undefined; + + const maybeStatus = document.querySelector( + ".artdeco-inline-feedback__message", + )?.innerText; + + if (maybeStatus === "No longer accepting applications") { + status = "expired"; } - browser.runtime.sendMessage({ type: "GOT_INFO_R", company, jobTitle, money, description, location, inperson_type: '' }); - } else if (message.type === "GOT_INFO_R") { - window.postMessage(message); - } + browser.runtime.sendMessage({ + type: "GOT_INFO_R", + company, + jobTitle, + money, + description, + location, + inperson_type, + status, + }); + return; + } + // Ignore everything that is no glassdoor + if (!window.location.host.includes("glassdoor")) return; + const company = document + .querySelector('header[data-test="job-details-header"]') + .children[0].children[0].querySelector("h4").innerHTML; + const jobTitle = document + .querySelector('header[data-test="job-details-header"]') + .querySelector("h1").innerHTML; + + const description = [ + ...document + .querySelector('header[data-test="job-details-header"]') + .parentNode.querySelectorAll("button"), + ].filter((a) => a.textContent == "Show more")[0]?.parentNode?.parentNode + ?.textContent; + + let money = + document.querySelectorAll( + 'div[class^="SalaryEstimate_salaryRange"]', + )?.[0]?.innerText ?? ""; + + const location = + document.querySelector('div[data-test="location"]')?.innerText ?? ""; + + const moneySectionNode = document.querySelector("section>section"); + if ( + moneySectionNode && + ["Base pay range", "Base pay"].includes( + moneySectionNode.querySelector("h2")?.textContent, + ) + ) { + money = + moneySectionNode.querySelector("div>div>div").children[1] + ?.textContent ?? ""; + } + + let status = undefined; + + if (!!document.querySelector("#expired-job-notice_Heading")) { + status = "expired"; + } + + browser.runtime.sendMessage({ + type: "GOT_INFO_R", + company, + jobTitle, + money, + description, + location, + inperson_type: "", + status, + }); +} +browser.runtime.onMessage.addListener((message) => { + if (message.type === "GET_DATA_FROM_PAGE") { + getPageData(); + } else if (message.type === "CHANGE_PAGE") { + window.location.href = message.new_url; + } else if ( + message.type === "MY_GET_URL_R" || + message.type === "GOT_INFO_R" || + message.type === "GOT_INTEREST" || + message.type === "AUTOLOAD_FOUND_GLASSDOOR_SEARCH" + ) { + window.postMessage(message); + } else if (message.type === "AUTOLOAD_FINISHED") { + if ( + window.location.href.includes("glassdoor") && + document.querySelector('a[data-test="for-you-page-link"]') + ) { + browser.runtime.sendMessage({ + type: "AUTOLOAD_FOUND_GLASSDOOR_SEARCH", + }); + return; + } + if ( + !window.location.href.includes("glassdoor") && + !window.location.href.includes("linkedin") + ) + return; + browser.runtime.sendMessage({ + type: "AUTOLOAD_NOTIFY_URL", + url: window.location.href, + }); + setTimeout(getPageData, 1000); + } }); window.addEventListener("message", (e) => { - if (e.data.type === "MY_GET_URL") { - browser.runtime.sendMessage({ type: "MY_GET_URL" }); - } else if (e.data.type === "HAS_EXTENSION_Q") { - window.postMessage({ type: "HAS_EXTENSION" }); - } else if (e.data.type === "REGISTER_INTEREST") { - browser.runtime.sendMessage({ type: "REGISTER_INTEREST" }); - } else if (e.data.type === "R_GET_DATA_FROM_PAGE") { - browser.runtime.sendMessage({ type: "R_GET_DATA_FROM_PAGE" }); + if (e.data.type === "MY_GET_URL") { + browser.runtime.sendMessage({ type: "MY_GET_URL" }); + } else if (e.data.type === "HAS_EXTENSION_Q") { + window.postMessage({ type: "HAS_EXTENSION" }); + } else if (e.data.type === "REGISTER_INTEREST") { + browser.runtime.sendMessage({ type: "REGISTER_INTEREST" }); + } else if (e.data.type === "R_GET_DATA_FROM_PAGE") { + browser.runtime.sendMessage({ type: "R_GET_DATA_FROM_PAGE" }); + } else if (e.data.type === "CHANGE_PAGE") { + browser.runtime.sendMessage({ + type: "CHANGE_PAGE", + new_url: e.data.new_url, + }); } }); diff --git a/extensions/manifest.json b/extensions/manifest.json index c743338..9b56a18 100644 --- a/extensions/manifest.json +++ b/extensions/manifest.json @@ -1,29 +1,36 @@ { - "manifest_version": 2, - "name": "Url Extractor Extension", - "version": "1.0", + "manifest_version": 2, + "name": "Url Extractor Extension", + "version": "1.0", - "description": "Allow my webpage to extract urls from other webpages", + "description": "Allow my webpage to extract urls from other webpages", - "content_scripts": [ - { - "matches": [""], - "js": ["definitions.js"], - "all_frames": true - } - ], + "content_scripts": [ + { + "matches": [""], + "js": ["definitions.js"], + "all_frames": true + } + ], - "permissions": ["activeTab", "menus", "tabs", "storage"], + "permissions": [ + "activeTab", + "menus", + "tabs", + "storage", + "webRequest", + "" + ], - "background": { - "scripts": ["background-script.js"], - "persistent": false, - "type": "module" - }, + "background": { + "scripts": ["background-script.js"], + "persistent": false, + "type": "module" + }, - "applications": { - "gecko": { - "id": "me@andr3h3nriqu3s.com" - } - } + "applications": { + "gecko": { + "id": "me@andr3h3nriqu3s.com" + } + } } diff --git a/site/src/routes/+page.svelte b/site/src/routes/+page.svelte index 380b0a9..a0fce0e 100644 --- a/site/src/routes/+page.svelte +++ b/site/src/routes/+page.svelte @@ -4,6 +4,8 @@ import ApplicationsList from './ApplicationsList.svelte'; import WorkArea from './work-area/WorkArea.svelte'; import ApplicationTypesList from './ApplicationTypesList.svelte'; + + let appList: ApplicationsList; @@ -11,8 +13,8 @@
- - + +
diff --git a/site/src/routes/ApplicationsList.svelte b/site/src/routes/ApplicationsList.svelte index 5270818..65888f2 100644 --- a/site/src/routes/ApplicationsList.svelte +++ b/site/src/routes/ApplicationsList.svelte @@ -49,9 +49,13 @@ } } + export function requestNext() { + applicationStore.loadItem = internal[0]; + } + function docKey(e: KeyboardEvent) { if (e.ctrlKey && e.code === 'KeyJ' && internal.length > 0) { - applicationStore.loadItem = internal[0]; + requestNext(); e.stopPropagation(); e.preventDefault(); return; @@ -94,10 +98,7 @@ }} role="none" > -
+

diff --git a/site/src/routes/work-area/AutoDropZone.svelte b/site/src/routes/work-area/AutoDropZone.svelte index 25ed900..7b25d41 100644 --- a/site/src/routes/work-area/AutoDropZone.svelte +++ b/site/src/routes/work-area/AutoDropZone.svelte @@ -3,9 +3,10 @@ import { statusStore } from '$lib/Types.svelte'; import { onMount } from 'svelte'; import DropZone from './DropZone.svelte'; - import { deleteR, put } from '$lib/utils'; + import { put } from '$lib/utils'; - let { index = $bindable() }: { index: number | undefined } = $props(); + let { index = $bindable(), onremove }: { index: number | undefined; onremove: () => void } = + $props(); const derivedItem: Application | undefined = $derived(applicationStore.all[index ?? -1]); @@ -31,35 +32,19 @@ applicationStore.loadItemOpen = false; } - async function remove() { - if (!derivedItem) return; - // Deactivate active item - try { - await deleteR(`application/${derivedItem.id}`); - } catch (e) { - // TODO: Show User - console.log('info data', e); - return; - } - applicationStore.removeByID(derivedItem.id); - index = undefined; - } - onMount(() => { statusStore.load(); }); {#if applicationStore.dragging && derivedItem} -
+
{#each statusStore.dirLinks[derivedItem.status_id] as node} moveStatus(node.id, node.endable)} >{node.name} {/each} - remove()}>Delete it + onremove()}>Delete it
{/if} diff --git a/site/src/routes/work-area/FoundExpire.svelte b/site/src/routes/work-area/FoundExpire.svelte new file mode 100644 index 0000000..257bcc2 --- /dev/null +++ b/site/src/routes/work-area/FoundExpire.svelte @@ -0,0 +1,114 @@ + + + { + if (timeout) clearTimeout(timeout); + }} +> +
+
+ +
+

Found Expired

+
+ + + +
+
+
diff --git a/site/src/routes/work-area/NewUrlDialog.svelte b/site/src/routes/work-area/NewUrlDialog.svelte index ee26bb0..04510a5 100644 --- a/site/src/routes/work-area/NewUrlDialog.svelte +++ b/site/src/routes/work-area/NewUrlDialog.svelte @@ -43,7 +43,7 @@ $effect(() => { function onMessage(e: MessageEvent) { - if (e.data.type === 'MY_GET_URL_R') { + if (dialog.open && e.data.type === 'MY_GET_URL_R') { if (e.data.error) { if (e.data.data.length === 0) { console.log('TODO inform user to mark page'); @@ -52,6 +52,7 @@ } return; } + if (!e.data.url) return; data.url = e.data.url ?? ''; window.requestAnimationFrame(() => { if (!form?.reportValidity()) { diff --git a/site/src/routes/work-area/SearchFound.svelte b/site/src/routes/work-area/SearchFound.svelte new file mode 100644 index 0000000..1f94744 --- /dev/null +++ b/site/src/routes/work-area/SearchFound.svelte @@ -0,0 +1,59 @@ + + + { + if (timeout) clearTimeout(timeout); + }} +> +
+
+ +
+

Found Glassdoor Search

+
+ + +
+
+
diff --git a/site/src/routes/work-area/Timeline.svelte b/site/src/routes/work-area/Timeline.svelte index 713cde9..0135562 100644 --- a/site/src/routes/work-area/Timeline.svelte +++ b/site/src/routes/work-area/Timeline.svelte @@ -6,7 +6,7 @@ } from '$lib/ApplicationsStore.svelte'; import { statusStore } from '$lib/Types.svelte'; - let { application, showAll }: { application: Application; showAll: boolean } = $props(); + let { application }: { application: Application } = $props(); let events: (ApplicationEvent & { timeDiff: string })[] = $state([]); @@ -91,14 +91,10 @@ class="shadow-sm shadow-violet-500 border rounded-full min-w-[50px] min-h-[50px] grid place-items-center bg-white z-10" > {#if event.event_type == EventType.Creation} - {:else if event.event_type == EventType.View} - {:else} import { applicationStore, type Application } from '$lib/ApplicationsStore.svelte'; - import { put, preventDefault, post, get } from '$lib/utils'; + import { put, preventDefault, post, get, deleteR } from '$lib/utils'; import { onMount } from 'svelte'; import ExtractTextDialog from './ExtractTextDialog.svelte'; import Flair from '../flair/Flair.svelte'; @@ -14,6 +14,11 @@ import CompanyField from './CompanyField.svelte'; import AutoDropZone from './AutoDropZone.svelte'; import { statusStore } from '$lib/Types.svelte'; + import SearchFound from './SearchFound.svelte'; + import FoundExpire from './FoundExpire.svelte'; + import ApplicationsList from '../ApplicationsList.svelte'; + + let { appList }: { appList: ApplicationsList } = $props(); // Not this represents the index in the store array let activeItem: number | undefined = $state(); @@ -23,6 +28,8 @@ let extractTokens: HTMLDialogElement; let changeUrl: HTMLDialogElement; let linkApplication: HTMLDialogElement; + let searchFound: SearchFound; + let foundExpire: FoundExpire; let lastExtData: any = $state(undefined); let autoExtData = false; @@ -60,12 +67,17 @@ lastExtData = undefined; } + let win: undefined | Window | null | true = $state(undefined); function openWindow(url: string) { if (!url.startsWith('https://')) { url = `https://${url}`; } - window.open( + if (win && hasExt) { + window.postMessage({ type: 'CHANGE_PAGE', new_url: url }); + return; + } + win = window.open( url, 'new window', `location,height=${window.screen.height},width=${window.screen.width},scrollbars,status,toolbar,menubar,popup` @@ -101,21 +113,44 @@ // // + let hasExt = $state(false); // Load Ext $effect(() => { function onMessage(e: MessageEvent) { if (e.data.type === 'GOT_INFO_R') { lastExtData = e.data; - if (autoExtData) { + if ((autoExtData || derivedItem?.title === 'New Application') && derivedItem?.simple_url) { + if (e.data.status === 'expired' && derivedItem?.status_id === null) { + foundExpire.open(); + } window.requestAnimationFrame(() => { setExtData(); }); } } + if (e.data.type === 'AUTOLOAD_FOUND_GLASSDOOR_SEARCH') { + console.log('Found glassdoor search'); + if (changeUrl.open) { + changeUrl.close(); + searchFound.open(); + } + return; + } + if (e.data.type === 'GOT_INTEREST') { + console.log('Has for ext and has id!'); + hasExt = true; + win = true; + } + if (e.data.type === 'HAS_EXTENSION') { + console.log('Has for ext!'); + hasExt = true; + } } window.addEventListener('message', onMessage); + console.log('Sending request for ext!'); window.postMessage({ type: 'REGISTER_INTEREST' }); + window.postMessage({ type: 'HAS_EXTENSION_Q' }); return () => { window.removeEventListener('message', onMessage); }; @@ -139,7 +174,14 @@ applicationStore.all[activeItem].inperson_type = ( lastExtData.inperson_type as string ).toLowerCase(); - applicationStore.all[activeItem].location = (lastExtData.location as string).split(',')[0]; + + if (lastExtData.location && lastExtData.location.includes(',')) { + applicationStore.all[activeItem].location = (lastExtData.location as string).split(',')[0]; + } else if (lastExtData.location && lastExtData.location.includes('·')) { + applicationStore.all[activeItem].location = (lastExtData.location as string) + .split('·')[0] + .trim(); + } console.log(lastExtData); @@ -213,6 +255,23 @@ console.log('info data', e); } } + + async function remove(autoNext = false) { + if (!derivedItem) return; + // Deactivate active item + try { + await deleteR(`application/${derivedItem.id}`); + } catch (e) { + // TODO: Show User + console.log('info data', e); + return; + } + applicationStore.removeByID(derivedItem.id); + activeItem = undefined; + if (autoNext) { + appList.requestNext(); + } + }
@@ -309,8 +368,7 @@ payrange[0] = payrange[0] * 8 * 5 * 4 * 12; if (payrange[1] != undefined) { payrange[1] = payrange[1] * 8 * 5 * 4 * 12; - applicationStore.all[activeItem!].payrange = - `${payrange[0]}-${payrange[1]}`; + applicationStore.all[activeItem!].payrange = `${payrange[0]}-${payrange[1]}`; window.requestAnimationFrame(() => save()); return; @@ -404,8 +462,7 @@ {item} allowDelete application={derivedItem} - updateApplication={(item) => - (applicationStore.all[activeItem ?? -1] = item)} + updateApplication={(item) => (applicationStore.all[activeItem ?? -1] = item)} /> {/each}
@@ -466,11 +523,7 @@ -
- + {:else}
-{/if} - -{#if derivedItem} activate(item, false)} /> + { + appList.requestNext(); + }} + /> + remove(true)} /> {/if}