mirror of
				https://github.com/open-webui/open-webui
				synced 2025-06-26 18:26:48 +00:00 
			
		
		
		
	enh: code block collapse
This commit is contained in:
		
							parent
							
								
									1cfa491179
								
							
						
					
					
						commit
						15cbccc8f5
					
				| @ -14,6 +14,9 @@ | ||||
| 	import { config } from '$lib/stores'; | ||||
| 	import { executeCode } from '$lib/apis/utils'; | ||||
| 	import { toast } from 'svelte-sonner'; | ||||
| 	import ChevronUp from '$lib/components/icons/ChevronUp.svelte'; | ||||
| 	import ChevronUpDown from '$lib/components/icons/ChevronUpDown.svelte'; | ||||
| 	import CommandLine from '$lib/components/icons/CommandLine.svelte'; | ||||
| 
 | ||||
| 	const i18n = getContext('i18n'); | ||||
| 
 | ||||
| @ -57,9 +60,14 @@ | ||||
| 	let result = null; | ||||
| 	let files = null; | ||||
| 
 | ||||
| 	let collapsed = false; | ||||
| 	let copied = false; | ||||
| 	let saved = false; | ||||
| 
 | ||||
| 	const collapseCodeBlock = () => { | ||||
| 		collapsed = !collapsed; | ||||
| 	}; | ||||
| 
 | ||||
| 	const saveCode = () => { | ||||
| 		saved = true; | ||||
| 
 | ||||
| @ -418,18 +426,39 @@ | ||||
| 				class="sticky {stickyButtonsClassName} mb-1 py-1 pr-2.5 flex items-center justify-end z-10 text-xs text-black dark:text-white" | ||||
| 			> | ||||
| 				<div class="flex items-center gap-0.5 translate-y-[1px]"> | ||||
| 					<button | ||||
| 						class="flex gap-1 items-center bg-none border-none bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-md px-1.5 py-0.5" | ||||
| 						on:click={collapseCodeBlock} | ||||
| 					> | ||||
| 						<div> | ||||
| 							<ChevronUpDown className="size-3" /> | ||||
| 						</div> | ||||
| 
 | ||||
| 						<div> | ||||
| 							{collapsed ? $i18n.t('Expand') : $i18n.t('Collapse')} | ||||
| 						</div> | ||||
| 					</button> | ||||
| 
 | ||||
| 					{#if lang.toLowerCase() === 'python' || lang.toLowerCase() === 'py' || (lang === '' && checkPythonCode(code))} | ||||
| 						{#if executing} | ||||
| 							<div class="run-code-button bg-none border-none p-1 cursor-not-allowed">Running</div> | ||||
| 						{:else if run} | ||||
| 							<button | ||||
| 								class="run-code-button bg-none border-none bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-md px-1.5 py-0.5" | ||||
| 								class="flex gap-1 items-center run-code-button bg-none border-none bg-gray-50 hover:bg-gray-100 dark:bg-gray-850 dark:hover:bg-gray-800 transition rounded-md px-1.5 py-0.5" | ||||
| 								on:click={async () => { | ||||
| 									code = _code; | ||||
| 									await tick(); | ||||
| 									executePython(code); | ||||
| 								}}>{$i18n.t('Run')}</button | ||||
| 								}} | ||||
| 							> | ||||
| 								<div> | ||||
| 									<CommandLine className="size-3" /> | ||||
| 								</div> | ||||
| 
 | ||||
| 								<div> | ||||
| 									{$i18n.t('Run')} | ||||
| 								</div> | ||||
| 							</button> | ||||
| 						{/if} | ||||
| 					{/if} | ||||
| 
 | ||||
| @ -457,65 +486,80 @@ | ||||
| 						: 'rounded-b-lg'} overflow-hidden" | ||||
| 			> | ||||
| 				<div class=" pt-7 bg-gray-50 dark:bg-gray-850"></div> | ||||
| 				<CodeEditor | ||||
| 					value={code} | ||||
| 					{id} | ||||
| 					{lang} | ||||
| 					onSave={() => { | ||||
| 						saveCode(); | ||||
| 					}} | ||||
| 					onChange={(value) => { | ||||
| 						_code = value; | ||||
| 					}} | ||||
| 				/> | ||||
| 
 | ||||
| 				{#if !collapsed} | ||||
| 					<CodeEditor | ||||
| 						value={code} | ||||
| 						{id} | ||||
| 						{lang} | ||||
| 						onSave={() => { | ||||
| 							saveCode(); | ||||
| 						}} | ||||
| 						onChange={(value) => { | ||||
| 							_code = value; | ||||
| 						}} | ||||
| 					/> | ||||
| 				{:else} | ||||
| 					<div | ||||
| 						class="bg-gray-50 dark:bg-black dark:text-white rounded-b-lg! pt-2 pb-2 px-4 flex flex-col gap-2 text-xs" | ||||
| 					> | ||||
| 						<span class="text-gray-500 italic"> | ||||
| 							{$i18n.t('{{COUNT}} hidden lines', { | ||||
| 								COUNT: code.split('\n').length | ||||
| 							})} | ||||
| 						</span> | ||||
| 					</div> | ||||
| 				{/if} | ||||
| 			</div> | ||||
| 
 | ||||
| 			<div | ||||
| 				id="plt-canvas-{id}" | ||||
| 				class="bg-gray-50 dark:bg-[#202123] dark:text-white max-w-full overflow-x-auto scrollbar-hidden" | ||||
| 			/> | ||||
| 
 | ||||
| 			{#if executing || stdout || stderr || result || files} | ||||
| 			{#if !collapsed} | ||||
| 				<div | ||||
| 					class="bg-gray-50 dark:bg-[#202123] dark:text-white rounded-b-lg! py-4 px-4 flex flex-col gap-2" | ||||
| 				> | ||||
| 					{#if executing} | ||||
| 						<div class=" "> | ||||
| 							<div class=" text-gray-500 text-xs mb-1">STDOUT/STDERR</div> | ||||
| 							<div class="text-sm">Running...</div> | ||||
| 						</div> | ||||
| 					{:else} | ||||
| 						{#if stdout || stderr} | ||||
| 					id="plt-canvas-{id}" | ||||
| 					class="bg-gray-50 dark:bg-[#202123] dark:text-white max-w-full overflow-x-auto scrollbar-hidden" | ||||
| 				/> | ||||
| 
 | ||||
| 				{#if executing || stdout || stderr || result || files} | ||||
| 					<div | ||||
| 						class="bg-gray-50 dark:bg-[#202123] dark:text-white rounded-b-lg! py-4 px-4 flex flex-col gap-2" | ||||
| 					> | ||||
| 						{#if executing} | ||||
| 							<div class=" "> | ||||
| 								<div class=" text-gray-500 text-xs mb-1">STDOUT/STDERR</div> | ||||
| 								<div | ||||
| 									class="text-sm {stdout?.split('\n')?.length > 100 | ||||
| 										? `max-h-96` | ||||
| 										: ''}  overflow-y-auto" | ||||
| 								> | ||||
| 									{stdout || stderr} | ||||
| 								</div> | ||||
| 								<div class="text-sm">Running...</div> | ||||
| 							</div> | ||||
| 						{/if} | ||||
| 						{#if result || files} | ||||
| 							<div class=" "> | ||||
| 								<div class=" text-gray-500 text-xs mb-1">RESULT</div> | ||||
| 								{#if result} | ||||
| 									<div class="text-sm">{`${JSON.stringify(result)}`}</div> | ||||
| 								{/if} | ||||
| 								{#if files} | ||||
| 									<div class="flex flex-col gap-2"> | ||||
| 										{#each files as file} | ||||
| 											{#if file.type.startsWith('image')} | ||||
| 												<img src={file.data} alt="Output" class=" w-full max-w-[36rem]" /> | ||||
| 											{/if} | ||||
| 										{/each} | ||||
| 						{:else} | ||||
| 							{#if stdout || stderr} | ||||
| 								<div class=" "> | ||||
| 									<div class=" text-gray-500 text-xs mb-1">STDOUT/STDERR</div> | ||||
| 									<div | ||||
| 										class="text-sm {stdout?.split('\n')?.length > 100 | ||||
| 											? `max-h-96` | ||||
| 											: ''}  overflow-y-auto" | ||||
| 									> | ||||
| 										{stdout || stderr} | ||||
| 									</div> | ||||
| 								{/if} | ||||
| 							</div> | ||||
| 								</div> | ||||
| 							{/if} | ||||
| 							{#if result || files} | ||||
| 								<div class=" "> | ||||
| 									<div class=" text-gray-500 text-xs mb-1">RESULT</div> | ||||
| 									{#if result} | ||||
| 										<div class="text-sm">{`${JSON.stringify(result)}`}</div> | ||||
| 									{/if} | ||||
| 									{#if files} | ||||
| 										<div class="flex flex-col gap-2"> | ||||
| 											{#each files as file} | ||||
| 												{#if file.type.startsWith('image')} | ||||
| 													<img src={file.data} alt="Output" class=" w-full max-w-[36rem]" /> | ||||
| 												{/if} | ||||
| 											{/each} | ||||
| 										</div> | ||||
| 									{/if} | ||||
| 								</div> | ||||
| 							{/if} | ||||
| 						{/if} | ||||
| 					{/if} | ||||
| 				</div> | ||||
| 					</div> | ||||
| 				{/if} | ||||
| 			{/if} | ||||
| 		{/if} | ||||
| 	</div> | ||||
|  | ||||
| @ -102,7 +102,7 @@ | ||||
| 	{/if} | ||||
| 
 | ||||
| 	<div | ||||
| 		class="w-full text-3xl text-gray-800 dark:text-gray-100 font-medium text-center flex items-center gap-4 font-primary" | ||||
| 		class="w-full text-3xl text-gray-800 dark:text-gray-100 text-center flex items-center gap-4 font-primary" | ||||
| 	> | ||||
| 		<div class="w-full flex flex-col justify-center items-center"> | ||||
| 			<div class="flex flex-row justify-center gap-3 @sm:gap-3.5 w-fit px-5"> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user